Table of content (TOC)


I’m not able to get working named anchors in Inkdrop. The purpose is to create e.g. a table of content as described here (Named Anchors) for example:

# Table of Contents
* [Chapter 1](#chapter-1)
* [Chapter 2](#chapter-2)
* [Chapter 3](#chapter-3)

which jumps to

## Chapter 1 <a id="chapter-1"></a>
Content for chapter one.

## Chapter 2 <a id="chapter-2"></a>
Content for chapter one.

## Chapter 3 <a id="chapter-3"></a>
Content for chapter one.

It seems Inkdrop doesn’t interpret Html at all - isn’t it?
Is there still a workaround for Inkdrop?
What about a Plugin for this?

Kind regards

Hi Nicolo,

Yes, it doesn’t support HTML for the security reason.
So currently your approach doesn’t work.
It’d be great if you made a plugin for this feature.
I guess this library would be helpful to make it:

Thanks for the report!

Hello craftzdog

Thanks for the reply. I fear i have not the programing skills neither the time to make a plugin. Although i have to admit, that the Plugin: Word Count documentation is so well made. On the other hand it would be easy to (manually) implement TOC, if Inkdrop would allow Html.

Could you explain how far Html support is a security matter for Inkdrop?

Kind regards

Inkdrop is obviously for personal use, so I guess you know that it’s safe to use HTML in notes. That’s right.
However it already supports publishing notes on the web. So it’d be possible dangerous for visitors. In addition, if the app supports additional sharing features in the future, HTML support will be a security matter.
Adding features is one way. I’d like to consider new features carefully that would affect others.

Your reasoning sounds conservative. In my understanding it’s like one would say it is potentially dangerous to visit a website.

Don’t take me wrong. I appreciate your attitude to take well pondered, carefully decisions. Users (like me ;)) often tend to desire more and more functionality. At the end Inkdrop is a Markdown notes app. I would propose to implement functionality which is generally considered as reasonable for Markdown.

Inkdrop uses remark-react for rendering Markdown and it prohibits from using HTML because of a potentially hazardous safety concern. Unfortunately it’s difficult to allow it in terms of implementation (I looked into it and tried before).
So it’d be good to be a plugin.

Yeah, I’m focusing on keeping the app simple and clean.
If it appeared that other people also want it, I’ll consider making it in the future.

Thanks again for your request!

It’s a pleasure to apply your very well designed Inkdrop app. Thanks a lot!

+1 I would love a table of contents generator with named anchors as well.

Also, a bottom right ↑ arrow on rendered page so you can click to scroll back to table of contents whenever

Hi here, made a plugin (locally) using remark-toc; it works well to generate table of contents but link doesn’t work.
TOC for:

# A

Generates TOC (source code in preview):

<a href="#a">...</a>

But A header has id user-content-a
I cannot configure remark-toc to prefix href neither remove user-content prefix.
How would you do @craftzdog?
Here my gist

I guess link hashes don’t work because the browser window will try to have the target named link at the top of the view. I mean, it will cause not only the preview but also the entire app view scrolled down.
So you need to handle clicking toc links to scroll to the right position in your plugin without using A links.

Hi, hashe works, but yes, scroll all view. Can you point documentation on how making preview scroll programmatically plz?

MDEPreview.remarkReactOptions is passed to the remark-react plugin. You can customize it as you like.

For example, you can override rendering A tag by doing something like:

const { MDEPreview } = inkdrop.components.classes
if (MDEPreview) {
  // just in case for other plugins
  var OrigA = MDEPreview.remarkReactOptions.remarkReactComponents.a
  MDEPreview.remarkReactOptions.remarkReactComponents.a = function CustomAComponent (props) {
    if (props.href && props.href.startsWith('#')) {
      // Add event handler
      return <a {...props} onClick={YOUR_HANDLER}>{props.children}</a>
    } else if (OrigA) {
      return <OrigA {...props}>{props.children}</OrigA>
    } else {
      return <a {...props}>{props.children}</a>

And in your click handler, scroll the .mde-preview viewport to the desired header.

1 Like

Thanks, how can I get .mde-preview element to do a XX.getElementById("YY").scrollIntoView()?


  • XX: Use JavaScript API
  • YY: Find a remark plugin to add slugs to headings

Plugin coded, you can now generate table of contents by adding ‘table of contents’ or ‘toc’ to your markdown file.

Do you have some code reviews advices?

Great job! I noticed the following:

  • Can you store a reference to the default behavior for MDEPreview.remarkReactOptions.remarkReactComponents.a in a variable and set it back on deactivation?
  • Scrolling using native JS instead of Jquery
  • Package name should be toc instead of inkdrop-toc

Looking forward to using your plugin!

1 Like

Thanks @anon29127703,
I removed jquery import but still using it (as jquery is part of electron inkdrop app) to keep animated scroll.
I rename package to toc
Not sure how to set back MDEPreview.remarkReactOptions.remarkReactComponents.a what would you do based on my code I tried something by I do not know if it will work.

Great work!
BTW, I will remove user-content- prefix in the next version so that TOC links in exported HTML works as well.

Not sure how to set back MDEPreview.remarkReactOptions.remarkReactComponents.a

Just restore the original A value:

this.MDEPreview.remarkReactOptions.remarkReactComponents.a = this.OrigA

I’m planning to remove jquery from the app dependency in the future. So I would encourage using vanilla JS API.


  • jQuery removed, I now use pure Vanilla
  • remarkReactComponents.a is restored now (I think)

OK for user-content-, let me know when it’s removed.


Thanks @anon956856!