Skip to content

Commit

Permalink
Add anchor headings to EIPs website (#2581)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanio authored Oct 28, 2020
1 parent 5140866 commit dbb6600
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 2 deletions.
109 changes: 109 additions & 0 deletions _includes/anchor_headings.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{% capture headingsWorkspace %}
{% comment %}
Version 1.0.5
https://github.com/allejo/jekyll-anchor-headings

"Be the pull request you wish to see in the world." ~Ben Balter

Usage:
{% include anchor_headings.html html=content %}

Parameters:
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll

Optional Parameters:
* beforeHeading (bool) : false - Set to true if the anchor should be placed _before_ the heading's content
* anchorAttrs (string) : '' - Any custom HTML attributes that will be added to the `<a>` tag; you may NOT use `href`, `class` or `title`
* anchorBody (string) : '' - The content that will be placed inside the anchor; the `%heading%` placeholder is available
* anchorClass (string) : '' - The class(es) that will be used for each anchor. Separate multiple classes with a space
* anchorTitle (string) : '' - The `title` attribute that will be used for anchors
* h_min (int) : 1 - The minimum header level to build an anchor for; any header lower than this value will be ignored
* h_max (int) : 6 - The maximum header level to build an anchor for; any header greater than this value will be ignored
* bodyPrefix (string) : '' - Anything that should be inserted inside of the heading tag _before_ its anchor and content
* bodySuffix (string) : '' - Anything that should be inserted inside of the heading tag _after_ its anchor and content

Output:
The original HTML with the addition of anchors inside of all of the h1-h6 headings.
{% endcomment %}

{% assign minHeader = include.h_min | default: 1 %}
{% assign maxHeader = include.h_max | default: 6 %}
{% assign beforeHeading = include.beforeHeading %}
{% assign nodes = include.html | split: '<h' %}

{% capture edited_headings %}{% endcapture %}

{% for _node in nodes %}
{% capture node %}{{ _node | strip }}{% endcapture %}

{% if node == "" %}
{% continue %}
{% endif %}

{% assign nextChar = node | replace: '"', '' | strip | slice: 0, 1 %}
{% assign headerLevel = nextChar | times: 1 %}

<!-- If the level is cast to 0, it means it's not a h1-h6 tag, so let's see if we need to fix it -->
{% if headerLevel == 0 %}
<!-- Split up the node based on closing angle brackets and get the first one. -->
{% assign firstChunk = node | split: '>' | first %}

<!-- If the first chunk does NOT contain a '<', that means we've broken another HTML tag that starts with 'h' -->
{% unless firstChunk contains '<' %}
{% capture node %}<h{{ node }}{% endcapture %}
{% endunless %}

{% capture edited_headings %}{{ edited_headings }}{{ node }}{% endcapture %}
{% continue %}
{% endif %}

{% assign _workspace = node | split: '</h' %}
{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
{% assign html_id = _idWorkspace[0] %}

{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}

<!-- Build the anchor to inject for our heading -->
{% capture anchor %}{% endcapture %}

{% if html_id and headerLevel >= minHeader and headerLevel <= maxHeader %}
{% capture anchor %}href="#{{ html_id }}"{% endcapture %}

{% if include.anchorClass %}
{% capture anchor %}{{ anchor }} class="{{ include.anchorClass }}"{% endcapture %}
{% endif %}

{% if include.anchorTitle %}
{% capture anchor %}{{ anchor }} title="{{ include.anchorTitle | replace: '%heading%', header }}"{% endcapture %}
{% endif %}

{% if include.anchorAttrs %}
{% capture anchor %}{{ anchor }} {{ include.anchorAttrs }}{% endcapture %}
{% endif %}

{% capture anchor %}<a {{ anchor }}>{{ include.anchorBody | replace: '%heading%', header | default: '' }}</a>{% endcapture %}

<!-- In order to prevent adding extra space after a heading, we'll let the 'anchor' value contain it -->
{% if beforeHeading %}
{% capture anchor %}{{ anchor }} {% endcapture %}
{% else %}
{% capture anchor %} {{ anchor }}{% endcapture %}
{% endif %}
{% endif %}

{% capture new_heading %}
<h{{ _hAttrToStrip }}
{{ include.bodyPrefix }}
{% if beforeHeading %}
{{ anchor }}{{ header }}
{% else %}
{{ header }}{{ anchor }}
{% endif %}
{{ include.bodySuffix }}
</h{{ _workspace | last }}
{% endcapture %}
{% capture edited_headings %}{{ edited_headings }}{{ new_heading }}{% endcapture %}
{% endfor %}
{% endcapture %}{% assign headingsWorkspace = '' %}{{ edited_headings | strip }}
2 changes: 1 addition & 1 deletion _layouts/eip.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h1 class="page-heading">
{% endif %}
</table>

{{ content }}
{% include anchor_headings.html html=content anchorClass="anchor-link" beforeHeading=true %}

<h2>Citation</h2>
<p>Please cite this document as:</p>
Expand Down
14 changes: 13 additions & 1 deletion assets/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,16 @@
# Only the main Sass file needs front matter (the dashes are enough)
---

@import "minima";
@import 'minima';

.page-content {
a.anchor-link {
width: 16px;
height: 16px;
display: inline-block;
margin-left: -22px;
&:hover {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='anchor-link-icon' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z'%3E%3C/path%3E%3C/svg%3E");
}
}
}

0 comments on commit dbb6600

Please sign in to comment.