How highlight.js works on codeblock?

I looked at the codes of codeblock.js and highlightblock.js. highlightblock added a postRender method to codeblockwidget, but this highlightblock is a widget, but it does not export the widget. I don’t understand how it works on codeblock.

Highlightblock modifies the CodeBlockWidget prototype and is not an independent widget it itself. As such, the module-type of widget isn’t strictly accurate for $:/plugins/tiddlywiki/highlight/highlightblock.js. Personally I use startup modules for such things.

Since the CodeBlockWidget prototype is modified, all subsequent uses of the CodeBlockWidget use the modified version which includes the postRender method.

This does not seem very reasonable and does not seem to be very scalable. I am thinking about how to add a copycode button to the codeblock, instead of needing to manually trigger the display of the copycode button; whether it is rewriting or extending the codeblock, the highlightblock.js code must be considered impact

1 Like

The Highlight.js plugin was written at a time when we did not have better options. I would recommend that you subclass the Codeblock widget and export it under the same name to modify it. Highlight.js should then use your modified Codeblock widget.

See https://tiddlywiki.com/dev/#WidgetSubclassingMechanism and this example.

3 Likes

@saqimtiaz Thank you, I’m going to use this too. But I’m not sure how to use class with it.

Maybe I can assign to constructor = class NewWidget extends CodeBlockWidget

I’m going to add a code execution button to it.

1 Like

It is also worth pointing out that as of TW v5.3, the preferred way to add a copy to clipboard button to the codeblock widget would be to define a custom widget via wikitext that overrides the core widget. Example:

\widget $codeblock(code)
<$macrocall $name="copy-to-clipboard" src=<<code>>/>
<$genesis $type="$codeblock" $remappable="no" code=<<code>>/>
\end

This can be tagged as a global and the appearance customized using CSS. If you want to invoke custom JavaScript when the button is clicked, write a custom action-widget and invoke that from the button widget that triggers the copying to clipboard.

This seems to be a bug. I also encountered this problem when rewriting the codeblock widget. I don’t know how this plugin template was written. It seems to be just a button and does not use the codeblock widget. This is very strange.

I checked the code related to this plugininfo template and did not find the use of codeblock.

See: plugininfo template

1 Like

That is really surprising indeed and was tricky to debug. It is caused by the transclude widget (and thus also by the macrocall widget which is used in the tabs macro) when used with the output type text/plain. The parser that wikifies the variable to retrieve the plain text output wraps the variable in a codeblock.

This reproduces the problem:

\widget $codeblock(code)
<$transclude $variable="copy-to-clipboard" src=<<code>>/>
<$genesis $type="$codeblock" $remappable="no" code=<<code>>/>
\end

\procedure myvariable() hello

<$transclude $variable="myvariable" $type="text/plain" $output="text/plain"/>

This usage of $codeblock in the core is very unexpected. I recommend to create a new widget with a different name to avoid clashing with the core:

\widget $code.block(code)
<$transclude $variable="copy-to-clipboard" src=<<code>>/>
<$genesis $type="$codeblock" $remappable="no" code=<<code>>/>
\end

Another possibility that occurs to me is to extend the core $codeblock widget to transclude its contents as children of the pre tag that it creates.

Then one could do the following:

<$codeblock code=<<code>> >
<$transclude $variable="copy-to-clipboard" src=<<code>>/>
</$codeblock>

If add a type field to tiddler, sucn as text/css or text/jpeg, it will also affect the output of the textI have temporarily excluded these types from the code. I am not sure if there are any bugs. It seems that modifying the codeblock does have a big impact. It turns out that tiddlywiki relies so much on the codeblock widget

Ouch! Did you have any thoughts about a fix? Can we just replace the codeblock widget with the equivalent HTML elements?

Thanks, so to my understanding, There are 2 ways to define new file types, one is to write a parser module , another is to write a cascade filter like

title: $:/plugins/linonetwo/tw-whiteboard/tiddlywiki-ui/EditTemplate/body/edit-whiteboard-cascade-filter
tags: $:/tags/EditTemplateBodyFilter
list-before: $:/config/EditTemplateBodyFilters/default

[field:type[application/vnd.tldraw+json]then[$:/plugins/linonetwo/tw-whiteboard/tiddlywiki-ui/EditTemplate/body/edit-whiteboard]]

(both will need a type description like

title: $:/language/Docs/Types/application/vnd.tldraw+json
description: Tldraw Whiteboard
name: application/vnd.tldraw+json
group: Developer
group-sort: 2

Which is better now? I think cascade way is easier to handle, because it is hard to hand write parser tree AST.

And in the comment, Jeremy said

The plain text parser processes blocks of source text into a degenerate parse tree consisting of a single text node

I don’t understand why use codeblock here, shouldn’t it be just “text node”?

I want to support suffixes with file names (as shown in the picture above), and modified highlight.jsblock.js. It seems to work well so far, but I found that it is only supported in markdown tiddler, and the vnd.tiddlywiki type seems Not supported (the code is wrapped in p tags, obviously codeblock is not working properly), this seems to be related to tiddlywiki’s parser

1 Like

This issue should now be resolved in the prerelease. It should now be possible to override the codeblock widget without impacting the tabs macro.

1 Like