diff options
Diffstat (limited to 'src/content/tils/2020/08/13')
-rw-r--r-- | src/content/tils/2020/08/13/code-jekyll.adoc | 102 |
1 files changed, 53 insertions, 49 deletions
diff --git a/src/content/tils/2020/08/13/code-jekyll.adoc b/src/content/tils/2020/08/13/code-jekyll.adoc index 6566928..6bd90b0 100644 --- a/src/content/tils/2020/08/13/code-jekyll.adoc +++ b/src/content/tils/2020/08/13/code-jekyll.adoc @@ -1,33 +1,35 @@ ---- -title: Anchor headers and code lines in Jekyll -date: 2020-08-13 -layout: post -lang: en -ref: anchor-headers-and-code-lines-in-jekyll ---- -The default Jekyll toolbox ([Jekyll][0], [kramdown][1] and [rouge][2]) doesn't -provide with a configuration option to add anchors to headers and code blocks. - -[0]: https://jekyllrb.com/ -[1]: https://kramdown.gettalong.org/ -[2]: http://rouge.jneen.net/ += Anchor headers and code lines in Jekyll -The best way I found of doing this is by creating a simple Jekyll plugin, more -specifically, a [Jekyll hook][3]. These allow you to jump in to the Jekyll build -and add a processing stage before of after Jekyll performs something. +:empty: +:jekyll: https://jekyllrb.com/ +:kramdown: https://kramdown.gettalong.org/ +:rouge: https://rouge.jneen.net/ +:jekyll-hook: https://jekyllrb.com/docs/plugins/hooks/ + +The default Jekyll toolbox ({jekyll}[Jekyll], {kramdown}[kramdown] and +{rouge}[rouge]) doesn't provide with a configuration option to add anchors to +headers and code blocks. -[3]: https://jekyllrb.com/docs/plugins/hooks/ +The best way I found of doing this is by creating a simple Jekyll plugin, more +specifically, a {jekyll-hook}[Jekyll hook]. These allow you to jump in to the +Jekyll build and add a processing stage before of after Jekyll performs +something. All you have to do is add the code to `_plugins/my-jekyll-plugin-code.rb`, and Jekyll knows to pick it up and call your code on the appropriate time. -## Anchor on headers +== Anchor on headers + +:jemoji: https://github.com/jekyll/jemoji +:jekyll-mentions: https://github.com/jekyll/jekyll-mentions +:html-regex: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 Since I wanted to add anchors to headers in all documents, this Jekyll hook works on `:documents` after they have been transformed into HTML, the `:post_render` phase: -```ruby +[source,ruby] +---- Jekyll::Hooks.register :documents, :post_render do |doc| if doc.output_ext == ".html" doc.output = @@ -37,30 +39,30 @@ Jekyll::Hooks.register :documents, :post_render do |doc| ) end end -``` - -I've derived my implementations from two "official"[^official] hooks, -[jemoji][4] and [jekyll-mentions][5]. +---- -[4]: https://github.com/jekyll/jemoji -[5]: https://github.com/jekyll/jekyll-mentions -[^official]: I don't know how official they are, I just assumed it because they - live in the same organization inside GitHub that Jekyll does. +I've derived my implementations from two +"official"{empty}footnote:official[ + I don't know how official they are, I just assumed it because they live in the + same organization inside GitHub that Jekyll does. +] hooks, {jemoji}[jemoji] and {jekyll-mentions}[jekyll-mentions]. All I did was to wrap the header tag inside an `<a>`, and set the `href` of that -`<a>` to the existing id of the header. Before the hook the HTML looks like: +`<a>` to the existing id of the header. Before the hook the HTML looks like: -```html +[source,html] +---- ...some unmodified text... <h2 id="my-header"> My header </h2> ...more unmodified text... -``` +---- And after the hook should turn that into: -```html +[source,html] +---- ...some unmodified text... <a href="#my-header"> <h2 id="my-header"> @@ -68,20 +70,18 @@ And after the hook should turn that into: </h2> </a> ...more unmodified text... -``` +---- The used regexp tries to match only h1-h6 tags, and keep the rest of the HTML -attributes untouched, since this isn't a general HTML parser, but the generated HTML -is somewhat under your control. Use at your own risk because -[you shouldn't parse HTML with regexps][6]. Also I used this strategy in my -environment, where no other plugins are installed. I haven't considered how this -approach may conflict with other Jekyll plugins. - -[6]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 +attributes untouched, since this isn't a general HTML parser, but the generated +HTML is somewhat under your control. Use at your own risk because +{html-regex}[you shouldn't parse HTML with regexps]. Also I used this strategy +in my environment, where no other plugins are installed. I haven't considered +how this approach may conflict with other Jekyll plugins. In the new anchor tag you can add your custom CSS class to style it as you wish. -## Anchor on code blocks +== Anchor on code blocks Adding anchors to code blocks needs a little bit of extra work, because line numbers themselves don't have preexisting ids, so we need to generate them @@ -90,7 +90,8 @@ without duplications between multiple code blocks in the same page. Similarly, this Jekyll hook also works on `:documents` in the `:post_render` phase: -```ruby +[source,ruby] +---- PREFIX = '<pre class="lineno">' POSTFIX = '</pre>' Jekyll::Hooks.register :documents, :post_render do |doc| @@ -111,25 +112,27 @@ Jekyll::Hooks.register :documents, :post_render do |doc| end end end -``` +---- This solution assumes the default Jekyll toolbox with code line numbers turned on in `_config.yml`: -```yaml +[source,yaml] +---- kramdown: syntax_highlighter_opts: span: line_numbers: false block: line_numbers: true -``` +---- The anchors go from B1-L1 to BN-LN, using the `code_block_counter` to track -which code block we're in and don't duplicate anchor ids. Before the hook the +which code block we're in and don't duplicate anchor ids. Before the hook the HTML looks like: -```html +[source,html] +---- ...some unmodified text... <pre class="lineno">1 2 @@ -138,11 +141,12 @@ HTML looks like: 5 </pre> ...more unmodified text... -``` +---- And after the hook should turn that into: -```html +[source,html] +---- ...some unmodified text... <pre class="lineno"><a id="B1-L1" href="#B1-L1">1</a> <a id="B1-L2" href="#B1-L2">2</a> @@ -150,6 +154,6 @@ And after the hook should turn that into: <a id="B1-L4" href="#B1-L4">4</a> <a id="B1-L5" href="#B1-L5">5</a></pre> ...more unmodified text... -``` +---- Happy writing :) |