diff --git a/README.md b/README.md
index 2ce2022e..50ffd455 100644
--- a/README.md
+++ b/README.md
@@ -262,11 +262,30 @@ When true any occurrence of a term will be linked no matter how it was spelled.
Paths or Glob-Patterns for files to include.
+### `--indexing.groupByHeadingDepth`
+
+- **Range:** `number` in [1-6]
+- **Since:** v3.4.0
+
+This option affects outputs generated with `generateFiles`. By default when
+indexing terms and markdown elements they are being grouped by the heading of
+the section they've been found in. In larger books with a lot of sections and
+subsections this can lead to *Index* files or *Tables of X* to be generated with
+lots of low-level sections and much detail. Yet sometimes it may be preferable
+to only list the book chapter or high-level sections which some element has been
+found in. This option allows to set the depth by which indexed elements shall be
+grouped where `1` refers to chapters (`#` headings). Note that grouping by
+high-level sections doesn't mean that only links to the high-level sections are
+generated. Where it makes sense links to low-level sections of occurrence are
+just being shortened.
+
### `--keepRawFiles` | `--r`
- **Range:** `string[]`
-Paths or Glob-Patterns for (markdown) files to copy to `outDir` but ignore in glossarification and linking. Non-markdown files will always be kept as is so no need to add those.
+Paths or Glob-Patterns for (markdown) files to copy to `outDir` but ignore in
+glossarification and linking. Non-markdown files will always be kept as is so no
+need to add those.
### `--linking` | `--l`
diff --git a/conf.schema.json b/conf.schema.json
index 18e36adb..6a8b2d88 100644
--- a/conf.schema.json
+++ b/conf.schema.json
@@ -149,10 +149,10 @@
"type": "object",
"properties": {
"groupByHeadingDepth": {
- "description": "Level of detail by which to group occurrences of terms or syntactic elements in generated files (Range [min; max] = [0; 9]). For example, use 0 to not group at all; 1 to group things at the level of document titles, etc. Configures the indexer. The option affects any files generated from the internal AST node index.",
+ "description": "Level of detail by which to group occurrences of terms or syntactic elements in generated files (Range [min, max]: [0, 6]). For example, use 0 to not group at all; 1 to group things at the level of document titles, etc. Configures the indexer. The option affects any files generated from the internal AST node index.",
"type": "number",
"minimum": 0,
- "maximum": 9,
+ "maximum": 6,
"default": 0
}
}
diff --git a/lib/index/figures.js b/lib/index/figures.js
index 1b7a6b98..6fdc7407 100644
--- a/lib/index/figures.js
+++ b/lib/index/figures.js
@@ -2,7 +2,7 @@ const {root, paragraph, text, heading, brk, link, list, listItem } = require("md
const {getFileLinkUrl} = require("../path/tools");
const {getLinkUrl, getNodeText} = require("../ast/tools");
-const {getIndex, getIndexValues: getValues, groupByHeading} = require("../indexer");
+const {getIndex, getIndexValues: getValues, group, byGroupHeading} = require("../indexer");
const api = {};
@@ -26,8 +26,7 @@ api.indices = [
,keyFn: (entry) => `${entry.file}#${entry.node.identifier}`
,filterFn: (entry) => entry.node.type === "definition"
}
-
-],
+];
/**
* Returns the markdown abstract syntax tree that is to be written to the file
@@ -59,13 +58,13 @@ api.getAST = function(context) {
*/
function getFiguresBySectionAst(context, figures) {
return paragraph(
- groupByHeading(figures).map((figures) => {
+ group(figures, byGroupHeading).map((figures) => {
const groupHeadingNode = figures[0].groupHeadingNode;
return paragraph([
- // add +1 to depth of headings referred to in order to keep
- // the title of the generated file the only depth-1 heading
brk
- ,heading(groupHeadingNode.depth + 1, text(getNodeText(groupHeadingNode)))
+ ,heading(groupHeadingNode.depth + 1, // [1]
+ text(getNodeText(groupHeadingNode))
+ )
,brk
,brk
,getListOfFiguresAst(context, figures)
@@ -73,6 +72,12 @@ function getFiguresBySectionAst(context, figures) {
]);
})
);
+ /**
+ * Implementation Notes:
+ *
+ * [1] add +1 to depth of headings referred to in order to keep
+ * the title of the generated file the only depth-1 heading
+ */
}
/**
diff --git a/lib/index/terms.js b/lib/index/terms.js
index 37312f10..9c0267b5 100644
--- a/lib/index/terms.js
+++ b/lib/index/terms.js
@@ -1,9 +1,9 @@
-const {root, paragraph, text, heading, brk, link } = require("mdast-builder");
+const {root, paragraph, text, heading, brk, link, html} = require("mdast-builder");
const Term = require("../model/term");
const {getFileLinkUrl} = require("../path/tools");
const {getLinkUrl, getNodeText} = require("../ast/tools");
-const {getIndex, groupByHeading} = require("../indexer");
+const {getIndex, group, byGroupHeading} = require("../indexer");
/**
* @typedef { import("./model/context") } Context
@@ -22,9 +22,8 @@ const {getIndex, groupByHeading} = require("../indexer");
* @type {Index}
*/
const api = {};
-const INDEX_ID = "index/terms/byTerm";
api.indices = [{
- id: INDEX_ID
+ id: "index/terms/byTerm"
,filterFn: (indexEntry) => indexEntry.node.type === "term-occurrence"
,keyFn: (indexEntry) => indexEntry.node.termDefs[0].term
}];
@@ -38,7 +37,7 @@ api.indices = [{
*/
api.getAST = function(context) {
const {indexFile} = context.opts.generateFiles;
- const indexEntries = getIndex(INDEX_ID);
+ const indexEntries = getIndex("index/terms/byTerm");
let title = "";
if (indexFile !== null && typeof indexFile === "object") {
title = indexFile.title;
@@ -81,7 +80,7 @@ function getIndexEntryAst(context, indexEntriesForTerm) {
*/
function getEntryLinksAst(context, indexEntriesForTerm) {
const indexFilename = getIndexFilename(context);
- const byHeadings = groupByHeading(indexEntriesForTerm);
+ const byHeadings = group(indexEntriesForTerm, byGroupHeading);
const links = [
...getGlossaryLinksAst(context, indexEntriesForTerm, indexFilename)
,...getDocumentLinksAst(context, byHeadings, indexFilename)
@@ -89,9 +88,8 @@ function getEntryLinksAst(context, indexEntriesForTerm) {
const linksSeparated = [];
for (let i = 0, len = links.length; i < len; i++) {
if (i > 0) {
- linksSeparated.push(text(" - "));
- } // link separator
-
+ linksSeparated.push(text(" \u25cb "));
+ }
linksSeparated.push(links[i]);
}
return linksSeparated;
@@ -137,11 +135,20 @@ function getDocumentLinksAst(context, byHeadings, fromIndexFilename) {
// prevent duplicate listing of glossary title (see also getGlossaryLinksAst())
return null;
} else {
- return link(ref, null, text(linkText));
+ const occurrencesAst = getLinksToOccurrenceAst(context, fromIndexFilename, indexEntryOccurrences);
+ if (occurrencesAst.length === 0) {
+ return link(ref, null, text(linkText));
+ } else {
+ return paragraph([
+ link(ref, null, text(linkText))
+ ,html(" ")
+ ,...occurrencesAst
+ ,html("")
+ ]);
+ }
}
})
.filter(linkNode => linkNode !== null);
-
// Implementation Notes:
// [1]: We get the index entries for all occurrences of a particular term
// below the given heading. Since we can only link to the heading but not
@@ -149,6 +156,32 @@ function getDocumentLinksAst(context, byHeadings, fromIndexFilename) {
// first term occurrence, solely.
}
+function getLinksToOccurrenceAst(context, fromIndexFilename, indexEntries) {
+ let {groupByHeadingDepth} = context.opts.indexing;
+ let i = 1;
+ return group(indexEntries, byHeading)
+ .map((entriesByHeading) => {
+ const { headingNode, file } = entriesByHeading[0];
+ if (headingNode && headingNode.depth > groupByHeadingDepth) {
+ const anchor = getLinkUrl(headingNode);
+ const ref = getFileLinkUrl(context, fromIndexFilename, file, anchor);
+ return link(ref, getNodeText(headingNode), text(`${i++} `));
+ }
+ })
+ .filter(html => html !== undefined);
+}
+
+function byHeading(indexEntry) {
+ const groupHeadingNode = indexEntry.headingNode;
+ const anchor = getLinkUrl(groupHeadingNode) || "";
+ let pos = "0";
+ if (groupHeadingNode) {
+ pos = groupHeadingNode.position.start.line;
+ }
+ // return key
+ return `${indexEntry.file}#${pos}:${anchor}`;
+}
+
/**
* @deprecated See https://github.com/about-code/glossarify-md/blob/master/CHANGELOG.md#deprecation-notices
* @param {Context} context
diff --git a/lib/indexer.js b/lib/indexer.js
index 1971edea..582abec9 100644
--- a/lib/indexer.js
+++ b/lib/indexer.js
@@ -31,8 +31,8 @@ const _index = {};
let _indexEntryId = 0;
/**
- * Builds an index of nodes by type and an index of definitions by id.
- * The index scope spans accross any visited files.
+ * Builds up indices from the `indices` configuration provided with `opts`.
+ *
* @param {Options} opts
* @returns {(tree: Node, vFile) => Node} mdast transformer
*/
@@ -45,6 +45,9 @@ api.indexer = function(opts) {
};
/**
+ * Returns the visitor that visits and indexes all the nodes of an AST according
+ * to the `indices` indexer option.
+ *
* @param {Options} opts indexer options
* @param {string} file currently visited document filename
* @returns {(node: Node) => void}
@@ -52,18 +55,19 @@ api.indexer = function(opts) {
function getNodeVisitor(opts, file) {
const {context} = opts;
const indices = opts.indices || [];
- const locate = getHeadingNodeLocator(context);
+ const setHeadingNodes = getHeadingNodesSetter(context);
return function visitor(node) {
_indexEntryId++;
const indexEntry = {
id: _indexEntryId
,node: node
+ ,file: file
,headingNode: null
,groupHeadingNode: null
- ,file: file
};
- locate(indexEntry);
+ setHeadingNodes(indexEntry);
+ // Indexing...
for (let i = 0, len = indices.length; i < len; i++) {
const idx = indices[i];
const id = idx.id;
@@ -81,17 +85,31 @@ function getNodeVisitor(opts, file) {
};
}
-function getHeadingNodeLocator(context) {
+/**
+ * Returns a function which takes an indexEntry and sets its `headingNode`
+ * and `groupHeadingNode` nodes based on the last visited heading nodes.
+
+ * ### Group Heading Node vs. Heading Node
+ *
+ * The `groupHeadingNode` depends on the configuration option
+ * `indexing.groupByHeadingDepth` and is the last visited heading node with a
+ * depth less or equal to `groupByHeadingDepth`. The group headings are used
+ * to decide the level of detail for rendering where some indexed item can be
+ * found in a book. For example users tell with a group heading depth of 1
+ * that they are interested only in the chapters where some indexed markdown
+ * element can be found but not necessarily the exact section. Nevertheless
+ * a reference to the exact section will also be stored with an index entry in
+ * `headingNode`.
+ *
+ * @param {Context} context
+ */
+function getHeadingNodesSetter(context) {
let {groupByHeadingDepth} = context.opts.indexing;
let lastVisitedGroupHeading = null;
let lastVisitedHeading = null;
- if (! groupByHeadingDepth ) {
- groupByHeadingDepth = 9;
- }
-
- return function locate(indexEntry) {
+ return function setter(indexEntry) {
const node = indexEntry.node;
- if (node.type === "heading" && node.depth <= 9) {
+ if (node.type === "heading" && node.depth <= 6) {
// Remember section of current node. Remember section at a depth
// configured via option 'indexing.groupByHeadingDepth'.
@@ -114,12 +132,20 @@ function getHeadingNodeLocator(context) {
};
}
+/**
+ * @param {string} indexId Id of an index as has been passed with `opts` to `indexer(opts)`
+ */
api.getIndex = function(indexId) {
if (Object.prototype.hasOwnProperty.call(_index, indexId)) {
return _index[indexId];
}
};
+/**
+ * @param {string} indexId Id of an index as has been passed with `opts` to `indexer(opts)`
+ * @param {string} key particular index key
+ * @returns {IndexEntry[]} index entries mapped onto key or empty array.
+ */
api.getIndexValues = function(indexId, key) {
const index = api.getIndex(indexId);
if (index) {
@@ -130,25 +156,25 @@ api.getIndexValues = function(indexId, key) {
};
/**
- * Returns an array of arrays where each `arr[i]` represents a list of index
- * entries and each `arr[i][j]` an `IndexEntry` for some AST node belonging to
- * a document heading used to group the nodes. So all `item[i][j].groupHeadingNode`
- * refer to the same heading AST node.
+ * Returns an array where each `arr[i]` represents another array of index
+ * entries that share the same group heading. Each `arr[i][j]` is an `IndexEntry`
+ * for some AST node where `item[i][j].groupHeadingNode` is the same heading AST
+ * node for every j at a given i.
*
- * item[i][j].headingNode and each item[i][j] an occurre
- * @returns {Array>}
+ * @param {IndexEntry[]} indexEntries Index entries to group by their `groupHeadingNode`
+ * @param {(IndexEntry) => string} [groupKeyFn] Function returning the key value to group by. If missing groups by `groupHeadingNode`
+ * @returns {Array}
*/
-api.groupByHeading = function(indexEntries) {
+api.group = function(indexEntries, groupKeyFn) {
const groups = {};
for (let i = 0, len = indexEntries.length; i < len; i++) {
const indexEntry = indexEntries[i];
- const groupHeadingNode = indexEntry.groupHeadingNode;
- const anchor = getLinkUrl(groupHeadingNode) || "";
- let pos = "0";
- if (groupHeadingNode) {
- pos = groupHeadingNode.position.start.line;
+ let key = null;
+ if (! groupKeyFn) {
+ key = api.byGroupHeading(indexEntry);
+ } else {
+ key = groupKeyFn.call(null, indexEntry);
}
- const key = `${indexEntry.file}#${pos}:${anchor}`;
if (! groups[key]) {
groups[key] = [];
}
@@ -162,4 +188,19 @@ api.groupByHeading = function(indexEntries) {
});
};
+/**
+ * Group key function to use with `group(indexEntries, groupKeyFn)`
+ * in order to group index entries by their `groupHeadingNode`.
+ */
+api.byGroupHeading = function(indexEntry) {
+ const groupHeadingNode = indexEntry.groupHeadingNode;
+ const anchor = getLinkUrl(groupHeadingNode) || "";
+ let pos = "0";
+ if (groupHeadingNode) {
+ pos = groupHeadingNode.position.start.line;
+ }
+ // return key
+ return `${indexEntry.file}#${pos}:${anchor}`;
+};
+
module.exports = api;
diff --git a/lib/main.js b/lib/main.js
index 88d69d8d..93de2103 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -58,12 +58,16 @@ function prepare(context) {
if (! opts.indexing ) {
opts.indexing = {};
}
+ if (! opts.indexing.groupByHeadingDepth) {
+ opts.indexing.groupByHeadingDepth = 6;
+ }
if (! opts.generateFiles ) {
opts.generateFiles = {};
}
if (! opts.glossaries ) {
opts.glossaries = {};
}
+
return Promise.resolve(context);
}
diff --git a/test/output-expected/config-indexFile/glossary-in-subdir/index.md b/test/output-expected/config-indexFile/glossary-in-subdir/index.md
index f78b76e3..93e838f7 100644
--- a/test/output-expected/config-indexFile/glossary-in-subdir/index.md
+++ b/test/output-expected/config-indexFile/glossary-in-subdir/index.md
@@ -2,7 +2,7 @@
## [Term](#term)
-[Glossary][1] - [Term][2]
+[Glossary][1] ○ [Term][2]
[1]: ./sub/glossary.md#term "GIVEN a term 'Term' AND option 'indexFile' is './index.md' AND the glossary file is in './sub/glossary.md' AND config option 'linking' is 'relative'
THEN the term MUST be linked with a path './sub/glossary.md#term'."
diff --git a/test/output-expected/config-indexFile/index-in-subdir/sub/index.md b/test/output-expected/config-indexFile/index-in-subdir/sub/index.md
index 1e53d141..9ff3c6bd 100644
--- a/test/output-expected/config-indexFile/index-in-subdir/sub/index.md
+++ b/test/output-expected/config-indexFile/index-in-subdir/sub/index.md
@@ -2,7 +2,7 @@
## [Term](#term)
-[Glossary][1] - [Term][2]
+[Glossary][1] ○ [Term][2]
[1]: ../glossary.md#term "GIVEN a term 'Term' AND option 'indexFile' is './sub/index.md' AND the glossary file is in './glossary.md' AND config option 'linking' is 'relative'
THEN the term MUST be linked with a path '../glossary.md#term'."
diff --git a/test/output-expected/config-indexFile/multiple-glossaries/index.md b/test/output-expected/config-indexFile/multiple-glossaries/index.md
index bd6b1e18..47b99484 100644
--- a/test/output-expected/config-indexFile/multiple-glossaries/index.md
+++ b/test/output-expected/config-indexFile/multiple-glossaries/index.md
@@ -2,15 +2,15 @@
## [In Glossary A and B](#in-glossary-a-and-b)
-[Glossary A][1] - [Glossary B][2] - [Shared set of terms][3]
+[Glossary A][1] ○ [Glossary B][2] ○ [Shared set of terms][3]
## [Only in Glossary A](#only-in-glossary-a)
-[Glossary A][4] - [Disjunct set of terms][5]
+[Glossary A][4] ○ [Disjunct set of terms][5]
## [Only in Glossary B](#only-in-glossary-b)
-[Glossary B][6] - [Disjunct set of terms][5]
+[Glossary B][6] ○ [Disjunct set of terms][5]
[1]: ./glossary-a.md#in-glossary-a-and-b
diff --git a/test/output-expected/config-indexFile/term-link-to-section/index.md b/test/output-expected/config-indexFile/term-link-to-section/index.md
index f8cd45d0..171a8084 100644
--- a/test/output-expected/config-indexFile/term-link-to-section/index.md
+++ b/test/output-expected/config-indexFile/term-link-to-section/index.md
@@ -2,7 +2,7 @@
## [Term](#term)
-[Glossary][1] - [Term][2] - [Section][3] - [./without-section-heading.md][4]
+[Glossary][1] ○ [Term][2] ○ [Section][3] ○ [./without-section-heading.md][4]
[1]: ./glossary.md#term "GIVEN a term 'Term' AND a document with a heading 'Section' AND the term is mentioned in that section
THEN in the index the term MUST be linked with a path './with-section-heading.md#section' AND a link label 'Section'."
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-0/figures.md b/test/output-expected/config-indexing/groupByHeadingDepth-0/figures.md
index b6ed5121..ba865c34 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-0/figures.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-0/figures.md
@@ -1,14 +1,42 @@
# [Figures](#figures)
-1. [Figure 1 depth 1][1]
-2. [Figure 2 depth 2][2]
-3. [Figure 3 depth 3][3]
-4. [Figure 4 depth 4][4]
-5. [Figure 5 depth 3][5]
-6. [Figure 6 depth 2][6]
-7. [Figure 7 depth 3][7]
-8. [Figure 8 depth 6][8]
-9. [Figure 9 depth 2][9]
+
+## [Testing option generateFiles.listOfFigures](#testing-option-generatefileslistoffigures)
+
+1. [Figure 1 depth 1][1]
+
+### [Heading 2 Depth 2](#heading-2-depth-2)
+
+1. [Figure 2 depth 2][2]
+
+#### [Heading 3 Depth 3](#heading-3-depth-3)
+
+1. [Figure 3 depth 3][3]
+
+##### [Heading 4 Depth 4](#heading-4-depth-4)
+
+1. [Figure 4 depth 4][4]
+
+#### [Heading 5 Depth 3](#heading-5-depth-3)
+
+1. [Figure 5 depth 3][5]
+
+### [Heading 6 Depth 2](#heading-6-depth-2)
+
+1. [Figure 6 depth 2][6]
+
+#### [Heading 7 Depth 3](#heading-7-depth-3)
+
+1. [Figure 7 depth 3][7]
+
+####### [Heading 8 Depth 6](#heading-8-depth-6)
+
+1. [Figure 8 depth 6][8]
+
+####### [Heading 9 Depth 2](#heading-9-depth-2)
+
+1. [Figure 9 depth 2][9]
+
[1]: ./document-figures.md#testing-option-generatefileslistoffigures
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-0/index.md b/test/output-expected/config-indexing/groupByHeadingDepth-0/index.md
index ef673406..c816217b 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-0/index.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-0/index.md
@@ -2,11 +2,11 @@
## [Term1](#term1)
-[Glossary][1] - [Document][2] - [Heading 2 Depth 2][3] - [Heading 3 Depth 3][4] - [Heading 4 Depth 4][5] - [Heading 5 Depth 3][6] - [Heading 6 Depth 2][7] - [Heading 7 Depth 3][8] - [Heading 8 Depth 6][9] - [Heading 9 Depth 2][10] - [Term1][11]
+[Glossary][1] ○ [Document][2] ○ [Heading 2 Depth 2][3] ○ [Heading 3 Depth 3][4] ○ [Heading 4 Depth 4][5] ○ [Heading 5 Depth 3][6] ○ [Heading 6 Depth 2][7] ○ [Heading 7 Depth 3][8] ○ [Heading 8 Depth 6][9] ○ [Heading 9 Depth 2][10] ○ [Term1][11]
## [Term2](#term2)
-[Glossary][12] - [Heading 2 Depth 2][3] - [Heading 3 Depth 3][4] - [Heading 4 Depth 4][5] - [Heading 5 Depth 3][6] - [Heading 6 Depth 2][7] - [Heading 7 Depth 3][8] - [Heading 8 Depth 6][9] - [Heading 9 Depth 2][10] - [Term2][13]
+[Glossary][12] ○ [Heading 2 Depth 2][3] ○ [Heading 3 Depth 3][4] ○ [Heading 4 Depth 4][5] ○ [Heading 5 Depth 3][6] ○ [Heading 6 Depth 2][7] ○ [Heading 7 Depth 3][8] ○ [Heading 8 Depth 6][9] ○ [Heading 9 Depth 2][10] ○ [Term2][13]
[1]: ./glossary.md#term1 "Term1 description."
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-1/index.md b/test/output-expected/config-indexing/groupByHeadingDepth-1/index.md
index 68fd89b8..902ef74a 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-1/index.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-1/index.md
@@ -2,14 +2,30 @@
## [Term1](#term1)
-[Glossary][1] - [Document][2]
+[Glossary][1] ○ [Document][2] [1 ][3][2 ][4][3 ][5][4 ][6][5 ][7][6 ][8][7 ][9][8 ][10]
## [Term2](#term2)
-[Glossary][3] - [Document][2]
+[Glossary][11] ○ [Document][2] [1 ][3][2 ][4][3 ][5][4 ][6][5 ][7][6 ][8][7 ][9][8 ][10]
[1]: ./glossary.md#term1 "Term1 description."
[2]: ./document-terms.md#document
-[3]: ./glossary.md#term2 "Term2 description."
+[3]: ./document-terms.md#heading-2-depth-2 "Heading 2 Depth 2"
+
+[4]: ./document-terms.md#heading-3-depth-3 "Heading 3 Depth 3"
+
+[5]: ./document-terms.md#heading-4-depth-4 "Heading 4 Depth 4"
+
+[6]: ./document-terms.md#heading-5-depth-3 "Heading 5 Depth 3"
+
+[7]: ./document-terms.md#heading-6-depth-2 "Heading 6 Depth 2"
+
+[8]: ./document-terms.md#heading-7-depth-3 "Heading 7 Depth 3"
+
+[9]: ./document-terms.md#heading-8-depth-6 "Heading 8 Depth 6"
+
+[10]: ./document-terms.md#heading-9-depth-2 "Heading 9 Depth 2"
+
+[11]: ./glossary.md#term2 "Term2 description."
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-2/index.md b/test/output-expected/config-indexing/groupByHeadingDepth-2/index.md
index 96e39312..ea46ba66 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-2/index.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-2/index.md
@@ -2,11 +2,11 @@
## [Term1](#term1)
-[Glossary][1] - [Document][2] - [Heading 2 Depth 2][3] - [Heading 6 Depth 2][4] - [Term1][5]
+[Glossary][1] ○ [Document][2] ○ [Heading 2 Depth 2][3] [1 ][4][2 ][5][3 ][6] ○ [Heading 6 Depth 2][7] [1 ][8][2 ][9][3 ][10] ○ [Term1][11]
## [Term2](#term2)
-[Glossary][6] - [Heading 2 Depth 2][3] - [Heading 6 Depth 2][4] - [Term2][7]
+[Glossary][12] ○ [Heading 2 Depth 2][3] [1 ][4][2 ][5][3 ][6] ○ [Heading 6 Depth 2][7] [1 ][8][2 ][9][3 ][10] ○ [Term2][13]
[1]: ./glossary.md#term1 "Term1 description."
@@ -14,10 +14,22 @@
[3]: ./document-terms.md#heading-2-depth-2
-[4]: ./document-terms.md#heading-6-depth-2
+[4]: ./document-terms.md#heading-3-depth-3 "Heading 3 Depth 3"
-[5]: ./glossary.md#term1
+[5]: ./document-terms.md#heading-4-depth-4 "Heading 4 Depth 4"
-[6]: ./glossary.md#term2 "Term2 description."
+[6]: ./document-terms.md#heading-5-depth-3 "Heading 5 Depth 3"
-[7]: ./glossary.md#term2
+[7]: ./document-terms.md#heading-6-depth-2
+
+[8]: ./document-terms.md#heading-7-depth-3 "Heading 7 Depth 3"
+
+[9]: ./document-terms.md#heading-8-depth-6 "Heading 8 Depth 6"
+
+[10]: ./document-terms.md#heading-9-depth-2 "Heading 9 Depth 2"
+
+[11]: ./glossary.md#term1
+
+[12]: ./glossary.md#term2 "Term2 description."
+
+[13]: ./glossary.md#term2
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-missing/figures.md b/test/output-expected/config-indexing/groupByHeadingDepth-missing/figures.md
index 695c83ed..b039490f 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-missing/figures.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-missing/figures.md
@@ -1,14 +1,42 @@
# [Figures](#figures)
-1. [Figure 1 depth 1][1]
-2. [Figure 2 depth 2][2]
-3. [Figure 3 depth 3][3]
-4. [Figure 4 depth 4][4]
-5. [Figure 5 depth 3][5]
-6. [Figure 6 depth 2][6]
-7. [Figure 7 depth 3][7]
-8. [Figure 8 depth 6][8]
-9. [Figure 9 depth 2][9]
+
+## [Document with Figure](#document-with-figure)
+
+1. [Figure 1 depth 1][1]
+
+### [Heading 2 Depth 2](#heading-2-depth-2)
+
+1. [Figure 2 depth 2][2]
+
+#### [Heading 3 Depth 3](#heading-3-depth-3)
+
+1. [Figure 3 depth 3][3]
+
+##### [Heading 4 Depth 4](#heading-4-depth-4)
+
+1. [Figure 4 depth 4][4]
+
+#### [Heading 5 Depth 3](#heading-5-depth-3)
+
+1. [Figure 5 depth 3][5]
+
+### [Heading 6 Depth 2](#heading-6-depth-2)
+
+1. [Figure 6 depth 2][6]
+
+#### [Heading 7 Depth 3](#heading-7-depth-3)
+
+1. [Figure 7 depth 3][7]
+
+####### [Heading 8 Depth 6](#heading-8-depth-6)
+
+1. [Figure 8 depth 6][8]
+
+####### [Heading 9 Depth 2](#heading-9-depth-2)
+
+1. [Figure 9 depth 2][9]
+
[1]: ./document-figures.md#document-with-figure
diff --git a/test/output-expected/config-indexing/groupByHeadingDepth-missing/index.md b/test/output-expected/config-indexing/groupByHeadingDepth-missing/index.md
index ef673406..c816217b 100644
--- a/test/output-expected/config-indexing/groupByHeadingDepth-missing/index.md
+++ b/test/output-expected/config-indexing/groupByHeadingDepth-missing/index.md
@@ -2,11 +2,11 @@
## [Term1](#term1)
-[Glossary][1] - [Document][2] - [Heading 2 Depth 2][3] - [Heading 3 Depth 3][4] - [Heading 4 Depth 4][5] - [Heading 5 Depth 3][6] - [Heading 6 Depth 2][7] - [Heading 7 Depth 3][8] - [Heading 8 Depth 6][9] - [Heading 9 Depth 2][10] - [Term1][11]
+[Glossary][1] ○ [Document][2] ○ [Heading 2 Depth 2][3] ○ [Heading 3 Depth 3][4] ○ [Heading 4 Depth 4][5] ○ [Heading 5 Depth 3][6] ○ [Heading 6 Depth 2][7] ○ [Heading 7 Depth 3][8] ○ [Heading 8 Depth 6][9] ○ [Heading 9 Depth 2][10] ○ [Term1][11]
## [Term2](#term2)
-[Glossary][12] - [Heading 2 Depth 2][3] - [Heading 3 Depth 3][4] - [Heading 4 Depth 4][5] - [Heading 5 Depth 3][6] - [Heading 6 Depth 2][7] - [Heading 7 Depth 3][8] - [Heading 8 Depth 6][9] - [Heading 9 Depth 2][10] - [Term2][13]
+[Glossary][12] ○ [Heading 2 Depth 2][3] ○ [Heading 3 Depth 3][4] ○ [Heading 4 Depth 4][5] ○ [Heading 5 Depth 3][6] ○ [Heading 6 Depth 2][7] ○ [Heading 7 Depth 3][8] ○ [Heading 8 Depth 6][9] ○ [Heading 9 Depth 2][10] ○ [Term2][13]
[1]: ./glossary.md#term1 "Term1 description."
diff --git a/test/output-expected/config-listOfFigures/option-title-missing/figures.md b/test/output-expected/config-listOfFigures/option-title-missing/figures.md
index 22f06e45..9090d953 100644
--- a/test/output-expected/config-listOfFigures/option-title-missing/figures.md
+++ b/test/output-expected/config-listOfFigures/option-title-missing/figures.md
@@ -1,5 +1,9 @@
# [Figures](#figures)
-1. [Figure 1 depth 1][1]
+
+## [Testing option generateFiles.listOfFigures](#testing-option-generatefileslistoffigures)
+
+1. [Figure 1 depth 1][1]
+
[1]: ./document.md#testing-option-generatefileslistoffigures