iamacup / react-native-markdown-display

React Native 100% compatible CommonMark renderer
MIT License
590 stars 169 forks source link

Soft line breaks inserted #136

Closed chmac closed 10 months ago

chmac commented 3 years ago

Firstly, thanks for this package, it's great. Super easy to get formatted text into RN. 👍

When I render foo\nbar\nbaz I get out:

foo
bar
baz

While the markdown spec says i should get foo bar baz.

I tried adding a custom markdownit like markdownit={MarkdownIt({ breaks: false })} but that hasn't made any change. When I debug the output I see this:

body
-paragraph
--textgroup
---text
---softbreak
---text
---softbreak
---text

I believe those soft breaks are either not supposed to be there, or are being rendered as actual breaks. I'm not really sure, just guessing. I can workaround it by removing the \n in my input. Plus, I'm not sure if it's an issue in this package or in markdown-it, but I figured I'd start here.

chmac commented 3 years ago

Ahhhh, I figured it out, softbreaks are rendered here:

https://github.com/iamacup/react-native-markdown-display/blob/50856add637320cb566bcd20a74ef4e91d99bdd4/src/lib/renderRules.js#L323-L327

I found this thread also which suggests its quite a complicated topic. I've added my own implementation in rules that renders softbreaks as spaces, so that fixes the issue for me, I hope!

Will leave this issue open in case you want to make a change, but feel free to close without comment if not.

chriswayg commented 3 years ago

I tried adding a custom markdownit like markdownit={MarkdownIt({ breaks: false })} but that hasn't made any change.

@iamacup Thanks for the very useful component. Overall it works very well.

I can confirm that the MarkdownIt({ breaks: false }) option has no effect at all in an Expo project (v. 41) as well as in a React Native project (0.63.4). - Is this acknowledged to be a bug?

I had to override the softbreak rule directly to get the behaviour which I find in most CommonMark compatible applications, which requires 2 spaces at the end of the line to get a line break. Here is the relevant code I am using to make the behaviour switchable:

import Markdown, {MarkdownIt} from 'react-native-markdown-display';
const markdownItInstance = MarkdownIt({typographer: true});

// Set to false to follow CommonMark app practice, or true to get visible line-breaks
const doBreak = false;
doBreak ? (breakChar = '\n') : (breakChar = ' ');

const copy = `
Line with two spaces 1  
Line with two spaces 2  
Line with two spaces 3  
Line with no spaces 1
Line with no spaces 2
Line with no spaces 3

(c) Copyright
`;

//...

return (
  <Markdown
    mergeStyle={false}
    markdownit={markdownItInstance}
    style={styles}
    rules={{
      softbreak: (node, children, parent, styles) => {
        return <Text key={node.key}>{breakChar}</Text>;
      },
    }}>
    {copy}
  </Markdown>
);

The image below illustrates the common default behaviour of soft line breaks with the example Markdown in MacDown (middle) as well as Typora (right): image