snarkdown icon indicating copy to clipboard operation
snarkdown copied to clipboard

Adds options object and syntax highlighting API

Open estrattonbailey opened this issue 7 years ago • 6 comments

Hey! I'm working on a project that calls for syntax highlighting so I figured I'd add it and see what you think.

Small sticky point with this PR: AFAIK, most highlighters escape HTML on their own, so if a user provides a options.hightlight function, I'm opting to skip the encodeAttr call and pass on that responsibility to the highlighter. If the code is pre-escaped, the highlighter re-escapes them i.e. &gt; from snarkdown becomes <span className>&amp;</span>gt<span className>;</span>.

Anyway, I'm just installing from my fork for now. Let me know if you want this refactored or anything else cleaned up. Also, if you feel this doesn't fit with this library, feel free to close this 👍🏼

estrattonbailey avatar Jun 29 '17 15:06 estrattonbailey

Good call. Is this what you were thinking?

Technically, it's still just over 1kb at 1027b according to your build script (which I'm totally stealing for my libs, btw). I removed the const lang ... from within the else...if block, since with gzip it was actually smaller. Any other suggestions?

After all this: perhaps from a perf standpoint, it would be better to let a syntax lib like Prism or Highlight do their thing asynchronously after page load. FWIW, I do still like the ease of a highlight option, but I might skip it for SSR perf on this project.

Example usage with Prism:

export default ({ string = '' }) => (
  <div className='karla markdown' dangerouslySetInnerHTML={{
    __html: md(string, {
      highlight: (str, lang) => prism.highlight(str, prism.languages[lang || 'markup'])
    })
  }} />
)

estrattonbailey avatar Jul 08 '17 15:07 estrattonbailey

Also, happy to squash those commits too, sorry to spam the history.

estrattonbailey avatar Jul 08 '17 15:07 estrattonbailey

More or less yup. I can always tweak sizing a bit to get things down.

What are your thoughts on this in the context of your comment about client-side lazy rendering? That's personally how I'd be setting things up, though rather than dangerouslySetInnerHTML I render the md() output using preact-markup. In that case it's actually already possible to upgrade the code blocks with highlighting (example, 2).

developit avatar Jul 08 '17 18:07 developit

Personally I think most projects could do fine with lazily highlighting client-side, though the perf hit is probably only very slight. I like the idea of converting to VDOM, but I'm also not super against dangerouslySetInnerHTML in many cases, so parsing and walking the tree after markdown finishes seems a little extra.

Do you find a lot of utility with converting to VDOM? Or would you recommend that most people just lazily highlight on the client? I'm leaning towards the latter for now, but am really interested in what could be done with markdown-to-VDOM. Didn't know that was a thing!

BTW thanks for taking the time on this, I know you must be busy!

estrattonbailey avatar Jul 08 '17 22:07 estrattonbailey

@estrattonbailey any update on this one ?

ritz078 avatar Aug 02 '17 18:08 ritz078

@ritz078 I decided to do the client-side highlighting, actually. There are probably good reasons to do it on the server, but I can't think of any off the top of my head.

I would recommend going the VDOM route as Jason has linked to on the Preact site. I've also worked with remark since this PR and its remark-react plugin and it's a nice experience. They also have a VDOM highlighting library that I haven't tried but would like to remark-react-lowlight.

That said, snarkdown is still my go-to for simple scenarios.

I imagine this PR can be closed, but I'll leave that up to @developit.

estrattonbailey avatar Aug 02 '17 18:08 estrattonbailey