Git Product home page Git Product logo

Comments (3)

iamacup avatar iamacup commented on September 22, 2024 1

Plugins for extra syntax support can be added using any markdown-it compatible plugins - see plugins for documentation from markdown-it. An example for integration follows:

Step 1

Identify the new components and integrate the plugin with a rendered compoonent. We can use the debugPrintTree property to see what rules we are rendering:

import React from 'react';
import { SafeAreaView, ScrollView, View, StatusBar } from 'react-native';

import Markdown, { MarkdownIt } from 'react-native-markdown-display';
import blockEmbedPlugin from 'markdown-it-block-embed';

const markdownItInstance = 
    MarkdownIt({typographer: true})
      .use(blockEmbedPlugin, {
        containerClassName: "video-embed"
      });

const copy = `
# Some header

@[youtube](lJIrF4YjHfQ)
`;

const App: () => React$Node = () => {
  return (
    <>
      <StatusBar/>
      <SafeAreaView>
        <ScrollView
          style={{height: '100%'}}
        >
          <View>
            <Markdown
              debugPrintTree
              markdownit={markdownItInstance}
            >
              {copy}
            </Markdown>
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

export default App;

In the console, we will see the following rendered tree:

body
-heading1
--textgroup
---text
-video

With the following error message:

Warning, unknown render rule encountered: video. 'unknown' render rule used (by default, returns null - nothing rendered) 

Step 2

We need to create the render rules and styles to handle this new 'video' component

import React from 'react';
import { SafeAreaView, ScrollView, View, StatusBar, Text } from 'react-native';

import Markdown, { MarkdownIt, getUniqueID } from 'react-native-markdown-display';
import blockEmbedPlugin from 'markdown-it-block-embed';

const markdownItInstance = 
    MarkdownIt({typographer: true})
      .use(blockEmbedPlugin, {
        containerClassName: "video-embed"
      });

const copy = `
# Some header

@[youtube](lJIrF4YjHfQ)
`;

const App: () => React$Node = () => {
  return (
    <>
      <StatusBar/>
      <SafeAreaView>
        <ScrollView
          style={{height: '100%'}}
        >
          <View>
            <Markdown
              debugPrintTree
              markdownit={markdownItInstance}
              style={{
                  video: {
                    color: 'red',
                  }
                }}
              rules={{
                  video: (node, children, parent, styles) =>{
                    // examine the node properties to see what video we need to render
                    console.log(node); // expected output of this is in readme.md below this code snip

                    return (<Text key={getUniqueID()} style={styles.video}>
                      Return a video component instead of this text component!
                    </Text>);
                  }
                   
                }}
            >
              {copy}
            </Markdown>
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

export default App;

And all of the video properties needed to render something meaningful are on the node, like this:

{type: "video", sourceType: "video", sourceInfo: {…}, sourceMeta: null, block: true, …}
  attributes: {}
  block: true
  children: []
  content: ""
  index: 1
  key: "rnmr_1720a98f540_video"
  markup: "@[youtube](lJIrF4YjHfQ)"
  sourceInfo:
    service: YouTubeService
      env: PluginEnvironment {md: MarkdownIt, options: {…}, services: {…}}
      name: "youtube"
      options:
        height: 390
        width: 640
      serviceName: "youtube"
      videoID: "lJIrF4YjHfQ"
      videoReference: "lJIrF4YjHfQ"
  sourceMeta: null
  sourceType: "video"
  tokenIndex: 5
  type: "video"

Other Debugging

You can do some additional debugging of what the markdown instance is spitting out like this:

import Markdown, { MarkdownIt } from 'react-native-markdown-display';
import blockEmbedPlugin from 'markdown-it-block-embed';

const markdownItInstance = 
    MarkdownIt({typographer: true})
      .use(blockEmbedPlugin, {
        containerClassName: "video-embed"
      });

const copy = `
# Some header

@[youtube](lJIrF4YjHfQ)
`;

// this shows you the tree that is used by the react-native-markdown-display
const astTree = markdownItInstance.parse(copy, {});
console.log(astTree);

//this contains the html that would be generated - not used by react-native-markdown-display but useful for reference
const html = markdownItInstance.render(copy);
console.log(html);

The above code will output something like this:

astTree:

(4) [Token, Token, Token, Token]

0: Token {type: "heading_open", tag: "h1", attrs: null, map: Array(2), nesting: 1, …}
1: Token {type: "inline", tag: "", attrs: null, map: Array(2), nesting: 0, …}
2: Token {type: "heading_close", tag: "h1", attrs: null, map: null, nesting: -1, …}
3: Token {type: "video", tag: "div", attrs: null, map: Array(2), nesting: 0, …}

length: 4
html:


<h1>Some header</h1>
<div class="video-embed block-embed-service-youtube"><iframe type="text/html" src="//www.youtube.com/embed/lJIrF4YjHfQ" frameborder="0" width="640" height="390" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>

from react-native-markdown-display.

lukeramsden avatar lukeramsden commented on September 22, 2024

I need this functionality too, and I had already planned to write my own markdown renderer with a custom video tag but this package seems like it will make my job much easier. I'll try and publish some sort of code when I get round to adding a video plugin to my code, although I don't have the time to turn it in to a real NPM package.

from react-native-markdown-display.

chriswayg avatar chriswayg commented on September 22, 2024

The above is the best explanation about how to integrate MarkdownIt plugins. Please make this part of the documentation rather than being tucked away in a closed issue.

I was able to get it to work with the markdown-it-mark highlighter plugin using the code above with the following relevant portions changed:

import Markdown, {MarkdownIt} from 'react-native-markdown-display';
import mark from 'markdown-it-mark';

const markdownItInstance = MarkdownIt({typographer: true}).use(mark, {});
const astTree = markdownItInstance.parse(copy, {});

//...
//...

    return (
      <Markdown
        markdownit={markdownItInstance}
        style={styles}
        rules={{
          mark: (node, children, parent, styles) => {
            return (
              <Text
                key={node.key}
                style={{
                  backgroundColor: '#FFF5AF',
                }}>
                {children}
              </Text>
            );
          },
        }}>
        {copy}
      </Markdown>
    );

from react-native-markdown-display.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.