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

Unexpected Changes in Article Headerlink and Missing Headerlink Icon #59

Closed
moon-jam opened this issue Sep 16, 2023 · 7 comments
Closed

Comments

@moon-jam
Copy link
Contributor

After installing hero-renderer-pandoc and uninstalling hexo-renderer-marked, I've noticed some unexpected behavior in my articles. The URLs for the article Header have been altered (such as an article titled 'header 123' would generate a URL like this: https://example.com/myarticle/#header-123 originally. However, with the changes, the URL format has been altered to https://example.com/myarticle/#header123) , and the headerlink icons(as shown in the screenshot below) that usually appear at the end of the titles are missing.
image

I would appreciate some guidance on resolving this issue or any insights into what might be causing these changes.

Thank you for your assistance!

@prinsss
Copy link

prinsss commented Jan 15, 2024

I've run into the same problem when switching from hexo-renderer-marked to hexo-renderer-pandoc.

The problem is that hexo-renderer-marked has some special handling, which adds a link element to the headings, but hexo-renderer-pandoc doesn't. Many themes depend on this behavior to show the anchor icon.

<!-- hexo-renderer-marked -->
<h3 id="Filter-Coordinate"><a href="#Filter-Coordinate" class="headerlink" title="Filter Coordinate"></a>Filter Coordinate</h3>

<!-- hexo-renderer-pandoc -->
<h3 id="filter-coordinate">Filter Coordinate</h3>

To align the behavior of hexo-renderer-pandoc with hexo-renderer-marked, I've created a Hexo script plugin, which adds the missing link element to the headings.

// FILE: scripts/fix-header-link.js
const { stripHTML } = require('hexo-util');

// When using hexo-renderer-marked, the header link is generated as follows:
// <h3 id="Filter-Coordinate"><a href="#Filter-Coordinate" class="headerlink" title="Filter Coordinate"></a>Filter Coordinate</h3>
// However, the header link generated by hexo-renderer-pandoc is:
// <h3 id="filter-coordinate">Filter Coordinate</h3>
// There are themes that rely on the "headerlink" element to show the anchor icon.
// So we need to mimic the behavior of hexo-renderer-marked.

hexo.extend.filter.register('after_post_render', (data) => {
  // https://github.com/hexojs/hexo-renderer-marked/blob/master/lib/renderer.js#L59
  data.content = data.content.replace(
    /<h([1-6]) id="(.+)">(.+?)<\/h[1-6]>/g,
    (match, level, id, content) => {
      const title = stripHTML(content);
      return `<h${level} id="${id}"><a href="#${id}" class="headerlink" title="${title}"></a>${content}</h${level}>`;
    }
  );

  return data;
});

Hope this helps. :)

@Ritsuka314
Copy link
Collaborator

One could also make a Pandoc filter, which works directly on Pandoc's internal syntax trees and is more robust than regular expressions.

@moon-jam
Copy link
Contributor Author

I've run into the same problem when switching from hexo-renderer-marked to hexo-renderer-pandoc.

The problem is that hexo-renderer-marked has some special handling, which adds a link element to the headings, but hexo-renderer-pandoc doesn't. Many themes depend on this behavior to show the anchor icon.

<!-- hexo-renderer-marked -->
<h3 id="Filter-Coordinate"><a href="#Filter-Coordinate" class="headerlink" title="Filter Coordinate"></a>Filter Coordinate</h3>

<!-- hexo-renderer-pandoc -->
<h3 id="filter-coordinate">Filter Coordinate</h3>

To align the behavior of hexo-renderer-pandoc with hexo-renderer-marked, I've created a Hexo script plugin, which adds the missing link element to the headings.

// FILE: scripts/fix-header-link.js
const { stripHTML } = require('hexo-util');

// When using hexo-renderer-marked, the header link is generated as follows:
// <h3 id="Filter-Coordinate"><a href="#Filter-Coordinate" class="headerlink" title="Filter Coordinate"></a>Filter Coordinate</h3>
// However, the header link generated by hexo-renderer-pandoc is:
// <h3 id="filter-coordinate">Filter Coordinate</h3>
// There are themes that rely on the "headerlink" element to show the anchor icon.
// So we need to mimic the behavior of hexo-renderer-marked.

hexo.extend.filter.register('after_post_render', (data) => {
  // https://github.com/hexojs/hexo-renderer-marked/blob/master/lib/renderer.js#L59
  data.content = data.content.replace(
    /<h([1-6]) id="(.+)">(.+?)<\/h[1-6]>/g,
    (match, level, id, content) => {
      const title = stripHTML(content);
      return `<h${level} id="${id}"><a href="#${id}" class="headerlink" title="${title}"></a>${content}</h${level}>`;
    }
  );

  return data;
});

Hope this helps. :)

Wow, it works, I really appreciate you.

@moon-jam moon-jam closed this as completed Apr 6, 2024
@moon-jam moon-jam reopened this Apr 6, 2024
@moon-jam
Copy link
Contributor Author

moon-jam commented Apr 6, 2024

One could also make a Pandoc filter, which works directly on Pandoc's internal syntax trees and is more robust than regular expressions.

Following your advice, I've added a Lua script (header-link-filter.lua) in the ./source/_data directory of my Hexo project. Here's the script for reference:

-- header-link-filter.lua
function Header(el)
    -- Create a link
    local link = pandoc.Link("", "#" .. el.identifier, "", pandoc.Attr("", {"headerlink"}))
  
    -- Insert the link into the header content
    table.insert(el.content, pandoc.Space())
    table.insert(el.content, link)
  
    return el

I've also updated my _config.yml to include the Lua filter along with other Pandoc arguments:

pandoc:
  args:
    - "-f"
    - "markdown"
    - "-t"
    - "html"
    - "--mathjax"
    - '--lua-filter'
    - './source/_data/header-link-filter.lua'

Everything is working smoothly now, and the headerlink icons are appearing as expected.

On a related note, I have also achieved the same functionality by modifying the source code of the hexo-renderer-pandoc plugin. You can view my changes here.

I'm considering making a pull request with these changes. Do you think that would be a good idea, or should I stick with the current approach using the Lua filter?

Thanks again for your helpful advice!

@Ritsuka314
Copy link
Collaborator

@moon-jam Nice job! Since _config.yml provides the interface, it is better not to hard-code it into the source code and maintain it as a separate module in a separate repo. We woundn't want to force everyone to use this filter; this should be an opt-in feature.

But maybe we should start a section in readme to give references to filters!

@moon-jam
Copy link
Contributor Author

moon-jam commented Apr 6, 2024

Okay, thanks. I created a separate repository for the header-link-filter.lua script.

I hope this makes it easier for you to reference the filter in README. Let me know if there's anything else I can do to help!

@Ritsuka314
Copy link
Collaborator

Thank you! I have updated readme. Please feel free to modify it if you don't like what I wrote.

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

No branches or pull requests

3 participants