6

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

Dmitry Shvedov
  • 3,169
  • 4
  • 39
  • 51
Alan Souza
  • 7,475
  • 10
  • 46
  • 68

4 Answers4

4

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.

Alan Souza
  • 7,475
  • 10
  • 46
  • 68
2

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.

Marcus Whybrow
  • 19,578
  • 9
  • 70
  • 90
1

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/

Marcus Whybrow
  • 19,578
  • 9
  • 70
  • 90
  • good one! But it still not there. I cannot edit the art as it is coming from outside of my library. I've update the question to reflect that. Thanks for your help! – Alan Souza Aug 24 '15 at 19:21
  • I recommend my [other answer](http://stackoverflow.com/a/32190663/166938). It works better for your precise situation. – Marcus Whybrow Aug 24 '15 at 19:58
0

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

          +--------+   +-------+    +-------+<br>
          |        |   + ditaa +    |       |<br>
          |  Text  |   +-------+    |diagram|<br>
          |Document|   |!magic!|    |       |<br>
          |        |   |       |    |       |<br>
          +---+----+   +-------+    +-------+
Allen
  • 927
  • 8
  • 19
  • Thanks @Allen, but I cannot do that as my library receives the art from outside where I have no control. Also, if I manually add the `
    ` tag, the rendered HTML is full of span tags.
    – Alan Souza Aug 24 '15 at 19:16
  • Any chance you could do a string replace on the source art before you render it? Maybe try and replace "\n" with "
    \n"
    – Allen Aug 24 '15 at 19:28