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

Parse HTML in news content #2

Closed
kennydee opened this issue Mar 30, 2015 · 17 comments
Closed

Parse HTML in news content #2

kennydee opened this issue Mar 30, 2015 · 17 comments

Comments

@kennydee
Copy link

Hi,

Thanks for the great work on this HN RN apps :)

I look at your code to know how you deal with one problem i faced with RN, and i finally see that you didn't face it right now : If you look at the "Dot matrix printer playing "eye of the tiger" [video]" news, you will see html <pre><code> in the middle of the content.

Did you have any idea, to transform those html code, in <Text style='pre'> or in other react componants like a <CodeHighlight> for example ? This is not just string replacement but something more difficult by replacing some part of the text by React Components.

It's difficult to explain why the problem seems difficult to resolve, but i hope you will understand me.

Thanks for sharing :)

@iSimar
Copy link
Owner

iSimar commented Mar 30, 2015

Hello Kennydee,

I understand what you're trying to say. I will try to implement the functionality within comment cells and update the code. I will comment back here once I am done.

@kennydee
Copy link
Author

Great :) thanks for your help

@iSimar
Copy link
Owner

iSimar commented Mar 30, 2015

Hello again,

I have updated the code.

Here is the link to the commit: 4a43178

You can see the changes I have made to comment cell in order to parse the code anchors.

Here is a screenshot of how it looks now: http://i.imgur.com/kO1azLk.png

@kennydee
Copy link
Author

First, thank you for your works, it help a lot.

This is a good start, but i think, you're missing one point : your implementation if i'm right, work only for one <pre><code> tag in a comment.
If there are multiple <pre><code> or other tag like <b> or even <img>, the whole thing need to be recoded ?

What do you think ?

i also will try something based on your work. Thanks you again

@iSimar
Copy link
Owner

iSimar commented Mar 30, 2015

Hello, I was thinking the same thing. Maybe there should be a view tag in react-native for parsing html code all together. Then a user can simply use the view like: <HTMLCode html={text} /> and it parses all the html tags. I can start working on such an element when I get time.

@kennydee
Copy link
Author

Hmm maybe.
My use case is a little bit more complicated because of a markup homemade more like bbcode :) but this is not the problem here.

The goal with React, i think, is to be able to do whatever you want after parsing :

  • for example, replace the <pre><code> with one React Component <CodeHighlight> dealing with code highlighting.
  • one <h2> tag with <Text style={styles.h2}>...</Text>
  • ...

I will digg on that and come back to you if i've got some ideas. Thanks

@iSimar
Copy link
Owner

iSimar commented Mar 30, 2015

I see, sounds fair. Okay.
Thanks, I look forward to your ideas/solutions.

@kennydee
Copy link
Author

I think i found a solution, by generating an array with React Component (for parse element) or string for normal text.

Here is the example (from my code, not the yours here sorry). Not really clean for now, but a good start :

_parseContent: function() {
    var content =this.props.news.content;

    //First, make a big string with all the parse replace by @@<parse>|<text>@@
    content = content.replace(/<b>(.*?)<\/b>/gmi, "@@bold|$1@@");
    content = content.replace(/<center>(.*?)<\/center>/gmi, "@@center|$1@@");
    content = content.replace(/<i>(.*?)<\/i>/gmi, "@@italic|$1@@");

    // split the string and treat manually each line, and find the appropriate tag
    return content.split('@@').map((text) => {
      if(text.indexOf('|') > -1) {
        var textWithoutTag = text.replace(/^(.*)\|/, '');
        switch(text.split('|')[0]) {
          case "bold":
            return <Text style={styles.bold}>{textWithoutTag}</Text>;
            break;
          case "center":
            return <Text style={styles.center}>{textWithoutTag}</Text>;
            break;
          case "italic":
            return <Text style={styles.italic}>{textWithoutTag}</Text>;
          default:
            return text;
        }
      }
      else {
        return text;
      }
    });
  },

and in the return of my render fonction :

<Text>{this._parseContent()}</Text>

WYT ?

Edit : i think it is far from perfect and probably don't work with multiple embedded tag like <b><i>Text</i></b> ...

@iSimar
Copy link
Owner

iSimar commented Mar 30, 2015

This is awesome! Great start, I'm working on the HTMLCode element right now.

@iSimar
Copy link
Owner

iSimar commented Mar 31, 2015

Hello again,

I have created a new component for such functionality, have a look:
https://github.com/iSimar/ParseHTML-React-Native

Let me know if this helps.

@kennydee
Copy link
Author

Whaou ! Really nice !

I think you ended in the same problem. How do you deal with <b><i>Text</i></b> ?
Right now, you don't ? :)

Is it possible to replace <code> with a <codeComponent> ? because if you are not able to do this, you can't use and map <img> and <a>tag, respectively to <Image> and <TouchableHighlight> component.

But the approach you have is excellent ! and a really good start ! It may even be enough for some use cases

@kennydee
Copy link
Author

Also just seen this which sounds interesting too : https://gist.github.com/jsdf/7f983f2cd955fd75d6cc

@iSimar
Copy link
Owner

iSimar commented Mar 31, 2015

I'm still working on parsing nested tags like <b><i>Text</i></b>. I also think <img> and <a> will also work.

@iSimar
Copy link
Owner

iSimar commented Mar 31, 2015

ParseHTML (https://github.com/iSimar/ParseHTML-React-Native) now supports nested tags. <b>Nested <i>Tags</i></b> works. I will now update HackerNews app to render comments using ParseHTML.

@iSimar
Copy link
Owner

iSimar commented Mar 31, 2015

This is what I have implemented for rendering comment text in comment cells:

<ParseHTML code = {this.props.comment.text} 
                     style = {styles.parseHTMLStyle}
                     customTagToStyle = {{
                                          '<pre>':{},
                                          '<code>': styles.commentCode
                                        }} />

@kennydee
Copy link
Author

kennydee commented Apr 1, 2015

Thanks, but the last version seems to not working with nested tags :

<ParseHTML
          code="Hello this is <b><i>Sample</i></b> HTML text. My name is <i>SpongeBob</i>, my bestfriend is <p>Patrick Star</p>. Lets use the code tag: <code>Hello World!</code>"
          customTagToStyle={{
                              "<p>": {fontSize: 30},
                              "<code>": [{color: "#FF7F50"}, {backgroundColor: "#000000"}]
                            }}/>

The text Sample is rendered in bold, but not in italic. Any idea ? Thanks

Here is a screenshot (also showing another bug with the </p> tag
capture_d_ecran_01_04_2015_10_48

@iSimar
Copy link
Owner

iSimar commented Apr 2, 2015

I have fixed the <p> bug, but I'm re-writing the ParseHTML project with a more scalable approach. Stay tuned. If you find anymore issues regarding ParseHTML, point it out on the main repository.

@iSimar iSimar closed this as completed Apr 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants