markdown-toc icon indicating copy to clipboard operation
markdown-toc copied to clipboard

Need example for custom TOC

Open flamusdiu opened this issue 7 years ago • 7 comments

I am creating a custom TOC to fix #104 for me; however, it's not that easy.

var toc = require('markdown-toc');
var md = '# heading\n## heading 2\n### heading 3';
var result = toc(md); // links are incorrect in the toc for Angular

var correct_toc = [];
result.json.forEach(function(h) {
    // fixed h.content
    correct_toc.push(new_h);
}

var toc_md = toc.bullets(correct_toc)
var toc = require('markdown-toc');

This fails due to https://github.com/jonschlinkert/markdown-toc/blob/e10f43ed5b38bc5c3fa87bbeedeaf9825898d33b/index.js#L156-L157

Calling the function, toc.bullets() directly doesn't work for me unless I remove L156 and change lvl to ele.i then it work.

I think an example or something documented to show how to actually create custom TOCs.

flamusdiu avatar Nov 28 '17 17:11 flamusdiu

try changing this line:

var toc_md = toc.bullets(correct_toc);

to:

var toc_md = toc.bullets(correct_toc, {highest: result.highest});

What might be easier is to pass a custom linkify function on the options and create the links however you want.

var result = toc(md, {
  linkify: function(tok, text, slug options) {
    // update tok.content to how you want it
    tok.content = `[${text}](something/#${slug})`;
    return tok;
  }
});

I'm going to leave this opened for now as a reminder to document the linkify option.

doowb avatar Nov 28 '17 18:11 doowb

Ahh, that's much easier. Why does it strip spaces in the title but then when you slugify it, it adds the dashes at for the empty spaces? For example: Heading <a href="heading"></a> gives a title of Heading but a slug of heading-- due to the extra spaces after the title.

flamusdiu avatar Nov 28 '17 19:11 flamusdiu

This is what I have from what you pointed out:

var result = toc('# me  <a href="me"></a>\n## me two\n### me three', {
 linkify: function(tok, text, slug, options) {
    const regex = /(.+\b)(.*)$/
    
    slug = slug.replace(regex, function(str, g1) { return g1; });
    tok.content = `[${text}](/articles#${slug})`;
    return tok;
 }
});

flamusdiu avatar Nov 28 '17 20:11 flamusdiu

So, that fixes the links but still doesn't work for Angular. I guess I need a custom renderer to add the proper syntax for the a tags.

flamusdiu avatar Nov 28 '17 20:11 flamusdiu

I ended up just changing the rules:

md.renderer.rules.link_open = function(tokens, idx, options /* env */) {
  var title = tokens[idx].title ? (' title="' + Remarkable.utils.escapeHtml(Remarkable.utils.replaceEntities(tokens[idx].title)) + '"') : '';
  var target = options.linkTarget ? (' target="' + options.linkTarget + '"') : '';
  
  return '<a [routerLink]="[\'/articles\']" fragment="' + Remarkable.utils.escapeHtml(tokens[idx].href.substr(1)) + '"' + title + target + '>';
};

Still doesn't work but it's an Angular issue atm.

flamusdiu avatar Nov 28 '17 22:11 flamusdiu

Just a note: I ended up using <a data-link="my-frag">My Link Text</a> and a custom onClick method to use the Angular Router process to get to the right page locations. I would think it would be easier with Angular.

flamusdiu avatar Dec 03 '17 14:12 flamusdiu

json rendering ignore options :(

adamsoffer avatar Aug 22 '20 20:08 adamsoffer