Markbind: Fenced code blocks: support highlighting words

Created on 24 Oct 2020  路  5Comments  路  Source: MarkBind/markbind

Current: we support highlighting specific lines in a code block

Suggestion: extend that feature to support highlighting specific parts of a line

c.Enhancement d.moderate f-CodeBlocks

All 5 comments

I remember seeing this in the issue tracker earlier, but can't find it now.
@ryoarmanda do you think the slicing syntax currently used for line highlighting can be extended to cover this feature?

For the part-of-text highlighting, I've discussed briefly about the technical concerns to it with @ang-zeyu under the original issue in the past (issue #1311 , starting from here) because the current flow inserts highlighting after syntax coloring, and so part-of-text highlighting would require reparsing and manipulation, which can be quite an effort.

I can try to investigate further whether the highlight addition can be done before syntax coloring.

As far as I can research, the highlightBlock() API in highlight.js can "preserve" HTML in code blocks, so it might be possible to add highlighting elements first before syntax coloring. The catch is that we need to ensure that the contents are HTML-escaped so it doesn't get wrongly disregarded from being a content (especially languages that use tags like HTML, XML, etc), and also that highlightBlock is expected to operate at the browser/DOM node level, as seen on the current implementation of highlightBlock which needs the document DOM variable.

I tried modifying the highlighting pipeline so it will eventually call highlightBlock() from ComponentParser but no dice. Looks like the node returned by htmlparser2 does not play well with highlight.js. Also, the function needs to have access to the DOM document variable. There is a very nice writeup on one of the linked projects of a similar request here (the Vermont one) that details about how they handle around it. They use another library called window to create a jsdom window, but they need to make the document variable global so highlightBlock can properly use it.

I think the window approach can be tried as well for our problem, but then again it will add another library to our project and declare a global variable, so I need to ask opinions to the maintainers first for this one. (cc: @ang-zeyu)

I tried modifying the highlighting pipeline so it will eventually call highlightBlock() from ComponentParser but no dice.

Thanks for researching this!

To clarify - the intention is to use window library but keep our slice syntax approach (not require pre-escaped input per the vermont implementation)

do you think the slicing syntax currently used for line highlighting can be extended to cover this feature?

I think words / whitespace delimited tokens should be more user friendly than characters using the same slice syntax ([i:j]).
We can accomodate characters via some suffix maybe ([1_c, 10_c]) if needed

global variable

this sounds problematic - the page generation is not exactly ordered at the moment (but also not undeterministic to the point where our tests would fail). It may also pose problems with parallelization of page generation (if we're aiming for that) in the future.

Is it possible to do it locally?

I don't think adding the window library is too much of an issue though; its also pretty small per https://www.npmjs.com/package/window


the alternative is to cheerio.parsehtml the output and manually add additional wrappers which can be very troublesome but not impossible to implement.

e.g. a simple case:

// if the highlight output is 

<span class="hljs">some text</span>

// and the highlight is word [0:1] (word 1), then
<span class="hljs"><span class="our-highlight-class">some</span> text</span>

Cons:

  • Not very performant but I think its fine since highlighting words is not a majority use case
  • may be rather troublesome / difficult to maintain for more complex structures

Thanks for looking into this @ryoarmanda @ang-zeyu

This is a niche feature. If we don't have it, no one will complain.
If we somehow manage to pull it off, we could be the _only_ such tool to support it. Good to be able to stand out in this crowded field. Of course, it is still possible that the price to pay is too high even if the reward is high, in which case we drop it.
So, we can keep exploring, but it is not a must-have feature.

Was this page helpful?
0 / 5 - 0 ratings