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

Possible feature? target anchor rather than header id #36

Closed
HenrikBechmann opened this issue Jan 7, 2018 · 2 comments
Closed

Possible feature? target anchor rather than header id #36

HenrikBechmann opened this issue Jan 7, 2018 · 2 comments

Comments

@HenrikBechmann
Copy link

It turns out that the best way to handle a fixed top toolbar for anchors (ie creating a top offset to avoid scrolling to a position under the toolbar), is to use a target anchor rather than a header id for the target.

So I've forked markdown-it-anchor to accommodate that. Thought you might be interested.

Basically: I've modified the processing logic as follows:

        if (slug == null) {
          slug = uniqueSlug(opts.slugify(title), slugs)
          token.attrPush(['class',opts.headerClassName])
          token.attrPush(['style','position:relative;padding-left:16px;margin-left:-16px;'])

          if (opts.useTargetlink) {

            opts.renderTargetlink(slug, opts, state, tokens.indexOf(token),title,token.tag)

          } else {

            token.attrPush(['id', slug])

          }
        }

        if (opts.permalink) {
          opts.renderPermalink(slug, opts, state, tokens.indexOf(token))
        }

some new options:

let defaults = {
  level: 1,
  slugify,
  permalink: false,
  renderPermalink,
  permalinkClass: 'header-anchor',
  permalinkSymbol: '¶',
  permalinkBefore: false,
  permalinkHref,
 // new...
  useTargetlink:false,
  renderTargetlink,
  targetlinkClass: 'target-anchor',
  headerClassName:'content-header',
}

To create the renderTargetLink I just copied and modified your renderPermalink.

Congrats on a well-written utility! It was very straightforward to fork and extend it.

Just thought you might be interested in case you want to accommodate this use case in your excellent plugin.

@nagaozen
Copy link
Collaborator

@valeriangalliat any thoughts about this?! This code smells... specially the token.attrPush(['style','position:relative;padding-left:16px;margin-left:-16px;'])

@HenrikBechmann
Copy link
Author

That particular line was a hack of mine. Please disregard for the purposes of this proposal.

Here's code for renderTargetLink

// added by HB, copied and modified renderPermalink
const renderTargetlink = (slug, opts, state, idx, text, tag) => {
  const space = () =>
    Object.assign(new state.Token('text', '', 0), { content: ' ' })

  const linkTokens = [
    Object.assign(new state.Token('link_open', 'a', 1), {
      attrs: [
        ['class', opts.targetlinkClass],
        ['id', slug],
        ['data-text',text],
        ['data-level',tag],
        ['aria-hidden', 'true']
      ]
    }),
    Object.assign(new state.Token('html_block', '', 0), { content: '' }),
    new state.Token('link_close', 'a', -1)
  ]

  // `push` or `unshift` according to position option.
  // Space is at the opposite side.
  linkTokens[position[(!opts.permalinkBefore).toString()]](space())
  state.tokens[idx + 1].children[position[opts.permalinkBefore]](...linkTokens)
}

here are the defaults for the new properties:

let defaults = {
 ...
  useTargetlink:false,
  renderTargetlink,
  targetlinkClass: 'target-anchor hash-anchor',
  headerClassName:'content-header',
}

here's the target-anchor class

a.target-anchor {
    position:absolute;
    top:-64px;
}

So, the point is, the permalink goes after the target anchor when selected, which places the link 64p below the link to leave room for the fixed title.

(I use hash-anchor for identification -- no styles -- to pull the anchors out of the dom for creation of a table of contents, so ignore that too)

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

2 participants