Skip to content

Commit

Permalink
0.8.0
Browse files Browse the repository at this point in the history
- Added function getTokensText similar to how it's done in markdown-it-anchor to support other ways of text extraction (fixes #61)
  • Loading branch information
Chris Maas committed Sep 10, 2024
1 parent d866954 commit aa9a1cc
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 18 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.8.0] - 2024-09-10

* **Added:** Option `getTokensText` to override how text is extracted from tokens to build headlines and slugs (fixes #61), similar to the function in markdown-it-anchor.

***

## [0.7.0] - 2024-09-09

* **Added:** Override the container element
* ⚠️ **BREAKING CHANGE:** The plugin moved from *inline mode* to *block mode* (fixes #62)
* **Changed:** Updated tests, readme etc.
* **Removed:** Old forceFullToc attribute

***
Expand Down
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# markdown-it-table-of-contents
A table of contents plugin for Markdown-it. Simple, customizable and with a default slugifier that matches that of https://www.npmjs.com/package/markdown-it-anchor (>5.0.0).
A table of contents plugin for Markdown-it. Simple, customizable and with a default slugifier that matches that of [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor) (>5.0.0).

## Usage

Expand Down Expand Up @@ -64,17 +64,18 @@ These options are available:

Name | Description | Default
-----------------------|-------------------------------------------------------------------------------------|------------------------------------
"includeLevel" | Headings levels to use (2 for h2:s etc) | [1, 2]
"containerClass" | The class for the container DIV | "table-of-contents"
"slugify" | A custom slugification function | `encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-'))`
"markerPattern" | Regex pattern of the marker to be replaced with TOC | `/^\[\[toc\]\]/im`
"listType" | Type of list (`ul` for unordered, `ol` for ordered) | `ul`
"format" | A function for formatting headings (see below) | `md.renderInline(content)`
"containerHeaderHtml" | Optional HTML string for container header | `undefined`
"containerFooterHtml" | Optional HTML string for container footer | `undefined`
"transformLink" | A function for transforming the TOC links | `undefined`
"transformContainerOpen"| A function for transforming the container opening tag | (see source code)
"transformContainerClose"| A function for transforming the container closing tag | (see source code)
`includeLevel` | Headings levels to use (2 for h2:s etc) | [1, 2]
`containerClass` | The class for the container DIV | "table-of-contents"
`slugify` | A custom slugification function | `encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-'))`
`markerPattern` | Regex pattern of the marker to be replaced with TOC | `/^\[\[toc\]\]/im`
`listType` | Type of list (`ul` for unordered, `ol` for ordered) | `ul`
`format` | A function for formatting headings (see below) | `md.renderInline(content)`
`containerHeaderHtml` | Optional HTML string for container header | `undefined`
`containerFooterHtml` | Optional HTML string for container footer | `undefined`
`transformLink` | A function for transforming the TOC links | `undefined`
`transformContainerOpen`| A function for transforming the container opening tag | (see source code)
`transformContainerClose`| A function for transforming the container closing tag | (see source code)
`getTokensText` | A function for extracting text from tokens for titles | (see source code)

`format` is an optional function for changing how the headings are displayed in the TOC.

Expand Down Expand Up @@ -112,6 +113,8 @@ md.use(markdownItTOC, {
});
```

`getTokensText` is a function that can be used to change how text is extracted from tokens to support more ways how headlines are build. See source code for more information or the equivalent function in [markdown-it-anchor](https://www.npmjs.com/package/markdown-it-anchor).

## Recommended plugins

By default, markdown-it-table-of-contents collects all headings and renders a nested list. It uses the `slugify()` function to create anchor targets for the links in the list. However, the headlines in your markdown document are not touched by markdown-it-table-of-contents. You'd have a nice table of contents, but the links don't link to anything. That's why you need another plugin to generate ids (anchor link targets) for all of your headlines. There are two recommended plugins to achieve this:
Expand Down
18 changes: 14 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const defaultOptions = {
containerFooterHtml: undefined,
transformLink: undefined,
transformContainerOpen: transformContainerOpen,
transformContainerClose: transformContainerClose
transformContainerClose: transformContainerClose,
getTokensText: getTokensText
};

/**
Expand All @@ -62,6 +63,17 @@ const defaultOptions = {
* @property {TocItem} parent Parent this item belongs to
*/

/**
* Helper to extract text from tokens, same function as in markdown-it-anchor
* @returns {string}
*/
function getTokensText(tokens) {
return tokens
.filter(t => ['text', 'code_inline'].includes(t.type))
.map(t => t.content)
.join('');
}

/**
* Finds all headline items for the defined levels in a Markdown document.
* @param {Array<number>} levels includeLevels like `[1, 2, 3]`
Expand All @@ -86,9 +98,7 @@ function findHeadlineElements(levels, tokens, options) {
}
}
else if (currentHeading && token.type === 'inline') {
const textContent = token.children
.filter((childToken) => childToken.type === 'text' || childToken.type === 'code_inline')
.reduce((acc, t) => acc + t.content, '');
const textContent = options.getTokensText(token.children);
currentHeading.text = textContent;
if (!currentHeading.anchor) {
currentHeading.anchor = options.slugify(textContent, token.content);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"license": "MIT",
"version": "0.7.0",
"version": "0.8.0",
"name": "markdown-it-table-of-contents",
"main": "index.js",
"scripts": {
Expand Down
13 changes: 13 additions & 0 deletions test/modules/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,17 @@ describe('Testing Markdown rendering', function () {
assert.equal(adjustEOL(md.render(basicMarkdown)), basicHTML);
done();
});

it('getTokensText', function (done) {
const md = new MarkdownIt();
md.use(markdownItTOC, {
getTokensText: tokens => tokens.filter(t => ['text', 'image'].includes(t.type)).map(t => t.content).join('')
});
assert.equal(
md.render('# H1 ![image](link) `code` _em_' + '\n' + '[[toc]]'),
'<h1>H1 <img src="link" alt="image"> <code>code</code> <em>em</em></h1>\n' +
'<div class="table-of-contents"><ul><li><a href="#h1-image-em">H1 image em</a></li></ul></div>\n'
);
done();
});
});

0 comments on commit aa9a1cc

Please sign in to comment.