Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Presets for Markdown #48

Closed
brownieboy opened this issue Jun 3, 2018 · 3 comments
Closed

Presets for Markdown #48

brownieboy opened this issue Jun 3, 2018 · 3 comments

Comments

@brownieboy
Copy link

brownieboy commented Jun 3, 2018

I've been experimenting with this very excellent library to try and implement a basic Markdown functionality. So far, I have bold, italics and strikethrough working. I wondering if there's any interest out there in a PR to add such functionality, or maybe setting it up as an add-on to it.

I've gone for the asterisks to denote bold text, underscores for italics and dashes for strikethrough. This follows what I'm used from using JIRA, although I don't how standard an implementation their's is!

The difficulty I had was ignoring whitespace and line breaks in the regex statements. The markdown character (asterisk, underscore or dash) has to be directly against the start and ending words, like so:

This should be bold bold text
This should not be bold * not bold text *
This should not be bold either * not bold text

This should be italic italic text
This should not be italic _ not italic text _
This should not be italic either _ not italic text

This should be strikethrough -strikethrough text-
This should not be strikethrough - not strikethrough text -
This should not be strikethrough either - not strikethrough text

Okay, so Github itself is actually rendering the italics and bold examples above! But it's not doing it for strikethrough, so you can see what I mean on that one.

Using https://regexr.com/, these are the regex patterns that I came up with:

const boldPattern = /(\s\*|^\*)(?=\S)([\s\S]*?\S)\*(?![*\S])/gm;
const italicPattern = /(\s_|^_)(?=\S)([\s\S]*?\S)_(?![_\S])/gm;
const strikethroughPattern = /(\s-|^-)(?=\S)([\s\S]*?\S)-(?![-\S])/gm;

Plugging in that in the configs for react-native-parsed-text, I came up with this:

export const markdownStyles = StyleSheet.create({
  bold: {
    fontWeight: "bold"
  },
  italic: {
    fontStyle: "italic"
  },
  strikethrough: {
    textDecorationLine: "line-through"
  }
});
const boldPattern = /(\s\*|^\*)(?=\S)([\s\S]*?\S)\*(?![*\S])/gm;
const italicPattern = /(\s_|^_)(?=\S)([\s\S]*?\S)_(?![_\S])/gm;
const strikethroughPattern = /(\s-|^-)(?=\S)([\s\S]*?\S)-(?![-\S])/gm;

const renderBoldText = (matchingString, matches) => {
  const match = matchingString.match(boldPattern);
  return `${match[0].replace(/\*(.*)\*/, "$1")}`;
};

const renderItalicText = (matchingString, matches) => {
  const match = matchingString.match(italicPattern);
  return `${match[0].replace(/_(.*)_/, "$1")}`;
};

const renderStrikethroughText = (matchingString, matches) => {
  const match = matchingString.match(strikethroughPattern);
  return `${match[0].replace(/-(.*)-/, "$1")}`;
};

export const parsedTextArray = [
  {
    // Bold (matching asterisks)
    pattern: boldPattern,
    style: markdownStyles.bold,
    renderText: renderBoldText
  },
  {
    // Italic (matching underscores)
    pattern: italicPattern,
    style: markdownStyles.italic,
    renderText: renderItalicText
  },
  {
    // strikethrough (matching dashes)
    pattern: strikethroughPattern,
    style: markdownStyles.strikethrough,
    renderText: renderStrikethroughText
  }
];

Anybody interested in my taking this any further?

@skizzo
Copy link

skizzo commented Jun 1, 2020

Thanks @brownieboy for the snippets, they're really helpful!
One question though, this works fine only for the first occurrence of the markdown pattern, so:

This is *some bold text*
is rendered as:
This is some bold text.

whereas

This is *the first*, and this *the second* bold text.
is rendered as:
This is the first, and this *the second* bold text.

Any ideas how to make this work for multiple matches? Thanks :)

@brownieboy
Copy link
Author

brownieboy commented Jun 2, 2020

@skizzo

Try these:

const boldPattern = /\*(\S(.*?\S)?)\*/gm;
const italicPattern = /_(\S(.*?\S)?)\_/gm;
const strikethroughPattern = /~((?:\[.*?\]|<.*?>(?:.*?<.*?>)?|`.*?`|.)*?)~/gm;

The first two taken from react-markdown-jsx, I think, so should work better than my first attempt.

@fbartho
Copy link
Contributor

fbartho commented Jun 11, 2020

Markdown is a crazy beast, and there are many flavors!

I'd support if we want to add this as an Example or Documentation, but I don't want us to add it to the default patterns or we'll have fights between "Standard Markdown" or "Markdown+" or "Github-Flavored Markdown" or others.

Additionally, as alternatives, there are other libraries more optimized for markdown. For example, as a transitive dependency, I've used this library: https://github.com/GetStream/react-native-simple-markdown

Is this something you or others are still interested in discussing? I'm going to close this for now, as it's over 2 years old, but if this is still interesting, we can reopen the ticket.

If you find a bug or have a PR, I'm working on a new release in #79

@fbartho fbartho closed this as completed Jun 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants