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

DOM-Based Plugins won't work (notably line-numbers) #1

Open
nicovank opened this issue Feb 9, 2017 · 9 comments
Open

DOM-Based Plugins won't work (notably line-numbers) #1

nicovank opened this issue Feb 9, 2017 · 9 comments

Comments

@nicovank
Copy link

nicovank commented Feb 9, 2017

The line-numbers plugin (and all the other plugins I have checked so far) won't work.

This is due to a statement in every of them:

if (typeof self === 'undefined' || !self.Prism || !self.document) {
	return;
}

which prevents anything from being registered. Further, most of them use the document and browser-only methods.

I guess the only way to make them work would be to rewrite all of them to make them work...

@jGleitz
Copy link
Owner

jGleitz commented Feb 9, 2017

I guess the only way to make them work would be to rewrite all of them to make them work...

Unfortunately, I guess you’re right. Most Prism plugins manipulate the DOM and can thus not be used outside the browser without further hassle.

There are some plugins that work though, like highlight-keywords.

If you want to use line-numbers anyway, you can do so quite easily. The plugin simply counts newlines in the output and adds a <span> for every line, which then gets to styled using CSS’s counters (see the plugin’s stylesheet).
That’s what I did for my personal website. I was disappointed to find that Prism’s plugins don’t really work outside the browser, too.

@EmmanuelBeziat
Copy link

Hi,
Shouldn’t you specify this point in the readme?

Aside this point, this plugin remain useful; prism isn't just "plain dead simple" to add to markdown-it, and this does the job very well.

@jGleitz
Copy link
Owner

jGleitz commented Jun 29, 2017

@EmmanuelBeziat I added a note and a link to this issue to the README.

Glad to hear that this plugin is nevertheless useful to you!

@sbrl
Copy link

sbrl commented Jul 6, 2021

Do you have a link to your website where you implement that at all @jGleitz? I can get the counter bit working, but I'm having a little trouble figuring out how to create a <span /> for every line (and the HTML structure you're specifically talking about there).

@jGleitz
Copy link
Owner

jGleitz commented Jul 7, 2021

@sbrl for my purposes, this simple regex replace did the trick (from code.pug):

const LINEREGEX = /\n(?!$)([\t ]*)(<[^>]*?class="[^>]*?comment[^>]*?>)?/g;
function wrapInLineSpans(code, idprefix) {
	let linespan = () => `<span class="line">`;
	if (typeof idprefix === 'string') {
		let lineindex = 1;
		linespan = () => `<span class="line" id="${lineid(idprefix, lineindex++)}">`;
	}
	return linespan() + code.replace(LINEREGEX, (match, nextLineStart, optionalComment) =>
		`</span>\n${optionalComment || ""}${linespan()}${nextLineStart}`);
}

If idprefix is set, then the code gives every line its own id. This allows having line references in the hash part of URIs.

Of course, this regex is bound to break on some input. However, it worked well for all code excerpts I had.

@jGleitz jGleitz changed the title Plugins won't work (notably line-numbers) DOM-Based Plugins won't work (notably line-numbers) Jul 7, 2021
@zackyjc
Copy link

zackyjc commented Aug 23, 2021

from prismjs.com: https://prismjs.com/plugins/line-numbers/
"Add the line-numbers class to your desired <pre> or any of its ancestors, and the Line Numbers plugin will take care of the rest. To give all code blocks line numbers, add the line-numbers class to the <body> of the page. This is part of a general activation mechanism where adding the line-numbers (or no-line-numbers) class to any element will enable (or disable) the Line Numbers plugin for all code blocks in that element. "

I insert line-numbers class to body, it works for me.

<body class='line-numbers' ...>
</body>

I actually have another question about line-highlight.

```javascript{10,12-22}
//  code
```

Insert data-line="{10,12-22}" to <pre> as follow, it also works:

<pre data-line="{10,12-22}" class="language-javascript line-numbers" tabindex="0">

Are there any markdown-it plugins that can do similar things?extract {...} from language{....} and insert <pre coustomname="{...}" >. A callback function is required for converting customname or {...}

for example:(I use markdown-it to convert MD file to HTML )

const md = require('markdown-it')();
const prism = require('markdown-it-xxxxplugin');

md.use(prism, {callback: xxxxCallbackFunction});
md.render(content)

@jGleitz
Copy link
Owner

jGleitz commented Aug 23, 2021

I insert line-numbers class to body, it works for me.

This probably means that you have prismjs installed on your site at runtime. This works, of course, but it is not how this plugin is meant to be used. Most use it to render static content, and since no DOM is presented at that time, line-numbers does not work.


Are there any markdown-it plugins that can do similar things?

I think you could try markdow-it-attrs. It will give you <pre><code data-line="foo"> for ```{data-line=foo}. If you want to have the attribute on the <pre> instead of the <code>, you can use a custom renderer, as described in the docs of markdown-it-attrs.

@andreas-mausch
Copy link

I've solved the line numbers like this (might not be perfect, but enough for my needs):

https://github.com/andreas-mausch/eleventy-sample/blob/82cca7f7166cb8147d4681d0ba6e7b720f1889ac/eleventy/markdown-it-prism-line-numbers.js

https://github.com/andreas-mausch/eleventy-sample/blob/82cca7f7166cb8147d4681d0ba6e7b720f1889ac/styles/_code.scss

markdown.options.highlight = lineNumbers(markdown.options.highlight)

@AleksandrHovhannisyan
Copy link

AleksandrHovhannisyan commented Oct 4, 2022

@andreas-mausch That works great for line numbering!

Any idea how I could use this to statically highlight a particular line of code? I'm currently using markdown-it-attrs to add file names to code blocks using a pseudo-element trick: https://github.com/AleksandrHovhannisyan/aleksandrhovhannisyan.com/blob/bced0ba4278a066334bed3ac710f53ab11838bb7/config/plugins/markdown.js#L26

The best I can think of is to have one :nth-child rule per line number, for maybe the most common lines, and then to target that line using something like pre[data-line-highlight="42"] .line-highlight:nth-of-type(42). With the code block looking like this in my source file:

```js {data-line-highlight="42"}
const foo = 'bar';
```

Edit: Hmm, this would only work for single-line highlights, not for multiline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants