Alan Souza
Alan Souza

Reputation: 7795

ReactJS: ascii art issue after JSX transformation

I'm trying to get an ascii art to be properly rendered by my React application.

After jsx-transformer is executed my art looses the format and renders pretty strange in the browser

My code:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
  <div id="content"></div>
  <script type="text/jsx">

    var App = React.createClass({
      render: function() {
        return (
          <pre>
            <code>
              +--------+   +-------+    +-------+
              |        |   + ditaa +    |       |
              |  Text  |   +-------+    |diagram|
              |Document|   |!magic!|    |       |
              |        |   |       |    |       |
              +---+----+   +-------+    +-------+
            </code>
          </pre>
        );
      }
    });

    var element = document.getElementById('content');
    React.render(React.createElement(App), element);
  </script>
</body>
</html>

Output:

enter image description here

If I remove react and add the pre code block directly to the html everything works fine.

Am I doing anything wrong here? Any help appreciated...

UPDATE 1: I cannot edit the ascii art.

UPDATE 2: I receive the art as a markdown file:

    +--------+   +-------+    +-------+
    |        | --+ ditaa +    |       |
    |  Text  |   +-------+    |diagram|
    |Document|   |!magic!|    |       |
    |        |   |       |    |       |
    +---+----+   +-------+    +-------+

After the markdown transformation to HTML this is the string I have:

<pre><code>+--------+   +-------+    +-------+
|        | --+ ditaa +    |       |
|  Text  |   +-------+    |diagram|
|Document|   |!magic!|    |       |
|        |   |       |    |       |
+---+----+   +-------+    +-------+
</code></pre>

I'm still using a JSX-loader to convert the HTML to JSX. The flow is markdown -> html -> jsx

Upvotes: 6

Views: 3821

Answers (4)

Alan Souza
Alan Souza

Reputation: 7795

So I ended up creating an issue in Github and Ben recommended to switch to Babel.

Here is the updated code that works just fine.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello World!</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser.min.js"></script>
</head>
<body>
  <div id="content"></div>
  <script type="text/babel">

    var App = React.createClass({
      render: function() {
        return (
          <pre>
            <code>{`
              +--------+   +-------+    +-------+
              |        |   + ditaa +    |       |
              |  Text  |   +-------+    |diagram|
              |Document|   |!magic!|    |       |
              |        |   |       |    |       |
              +---+----+   +-------+    +-------+
            `}</code>
          </pre>
        );
      }
    });

    var element = document.getElementById('content');
    React.render(React.createElement(App), element);
  </script>
</body>
</html>

Actually adding the {` ... `} works with jsx-transformer. But I'm not sure why it works.

UPDATE: It works because of template literals. Their recommendation is to use babel regardless because JSXTransformer has been deprecated.

Upvotes: 5

Marcus Whybrow
Marcus Whybrow

Reputation: 19998

If you're stuck with inseparable tags and ASCII you can use dangerouslySetInnerHTML:

var App = React.createClass({
  render: function() {

    // My representation of your input ASCII you get from elsewhere
    var inputASCII = [
      "<pre><code>+--------+   +-------+    +-------+",
      "|        |   + ditaa +    |       |",
      "|  Text  |   +-------+    |diagram|",
      "|Document|   |!magic!|    |       |",
      "|        |   |       |    |       |",
      "+---+----+   +-------+    +-------+",
      "</code></pre>",
    ].join('\n');

    // dangerouslySetInnerHTML expects an object like this:
    var wrappedASCII = {__html: inputASCII };

    return <span dangerouslySetInnerHTML={wrappedASCII}></span>;
  }
});

https://jsfiddle.net/yy31xqa3/5/

This functionality is mainly provided for cooperation with DOM string manipulation libraries

Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. https://facebook.github.io/react/tips/dangerously-set-inner-html.html

Only use this solution if you trust the source of the ASCII not to inject <script> tags or other malicious HTML.

Upvotes: 2

Marcus Whybrow
Marcus Whybrow

Reputation: 19998

Try adding \n characters between lines before hand:

var App = React.createClass({
  render: function() {
    var ascii = [
      "+--------+   +-------+    +-------+",
      "|        |   + ditaa +    |       |",
      "|  Text  |   +-------+    |diagram|",
      "|Document|   |!magic!|    |       |",
      "|        |   |       |    |       |",
      "+---+----+   +-------+    +-------+",
    ].join('\n');

    return (
      <pre>
        <code>
          {ascii}
        </code>
      </pre>
    );
  }
});

https://jsfiddle.net/yy31xqa3/

Upvotes: 1

Allen
Allen

Reputation: 927

Try manually adding a linebreak to the end of each line, ex:

          +--------+   +-------+    +-------+<br>
          |        |   + ditaa +    |       |<br>
          |  Text  |   +-------+    |diagram|<br>
          |Document|   |!magic!|    |       |<br>
          |        |   |       |    |       |<br>
          +---+----+   +-------+    +-------+

Upvotes: 0

Related Questions