Skip to content

Commit e852602

Browse files
committed
feat: add mdx support
1 parent 95715a3 commit e852602

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

doctoc.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ function cleanPath(path) {
1616
return homeExpanded.replace(/\s/g, '\\ ');
1717
}
1818

19-
function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly) {
19+
function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly, syntax) {
2020
if (processAll) {
2121
console.log('--all flag is enabled. Including headers before the TOC location.')
2222
}
2323

2424
if (updateOnly) {
2525
console.log('--update-only flag is enabled. Only updating files that already have a TOC.')
2626
}
27-
27+
2828
console.log('\n==================\n');
2929

3030
var transformed = files
3131
.map(function (x) {
3232
var content = fs.readFileSync(x.path, 'utf8')
33-
, result = transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly);
33+
, result = transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly, syntax);
3434
result.path = x.path;
3535
return result;
3636
});
@@ -48,7 +48,7 @@ function transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPref
4848
console.log('"%s" is up to date', x.path);
4949
});
5050

51-
changed.forEach(function (x) {
51+
changed.forEach(function (x) {
5252
if (stdOut) {
5353
console.log('==================\n\n"%s" should be updated', x.path)
5454
} else {
@@ -62,7 +62,7 @@ function printUsageAndExit(isErr) {
6262

6363
var outputFunc = isErr ? console.error : console.info;
6464

65-
outputFunc('Usage: doctoc [mode] [--entryprefix prefix] [--notitle | --title title] [--maxlevel level] [--all] [--update-only] <path> (where path is some path to a directory (e.g., .) or a file (e.g., README.md))');
65+
outputFunc('Usage: doctoc [mode] [--entryprefix prefix] [--notitle | --title title] [--maxlevel level] [--all] [--update-only] [--syntax (md|mdx)] <path> (where path is some path to a directory (e.g., .) or a file (e.g., README.md))');
6666
outputFunc('\nAvailable modes are:');
6767
for (var key in modes) {
6868
outputFunc(' --%s\t%s', key, modes[key]);
@@ -84,7 +84,7 @@ var mode = modes['github'];
8484

8585
var argv = minimist(process.argv.slice(2)
8686
, { boolean: [ 'h', 'help', 'T', 'notitle', 's', 'stdout', 'all' , 'u', 'update-only'].concat(Object.keys(modes))
87-
, string: [ 'title', 't', 'maxlevel', 'm', 'entryprefix' ]
87+
, string: [ 'title', 't', 'maxlevel', 'm', 'entryprefix', 'syntax' ]
8888
, unknown: function(a) { return (a[0] == '-' ? (console.error('Unknown option(s): ' + a), printUsageAndExit(true)) : true); }
8989
});
9090

@@ -104,7 +104,7 @@ var entryPrefix = argv.entryprefix || '-';
104104
var processAll = argv.all;
105105
var stdOut = argv.s || argv.stdout
106106
var updateOnly = argv.u || argv['update-only']
107-
107+
var syntax = argv['syntax'] || "md"
108108
var maxHeaderLevel = argv.m || argv.maxlevel;
109109
if (maxHeaderLevel && isNaN(maxHeaderLevel) || maxHeaderLevel < 0) { console.error('Max. heading level specified is not a positive number: ' + maxHeaderLevel), printUsageAndExit(true); }
110110

@@ -120,7 +120,7 @@ for (var i = 0; i < argv._.length; i++) {
120120
files = [{ path: target }];
121121
}
122122

123-
transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly);
123+
transformAndSave(files, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, stdOut, updateOnly, syntax);
124124

125125
console.log('\nEverything is OK.');
126126
}

lib/file.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var path = require('path')
22
, fs = require('fs')
33
, _ = require('underscore');
44

5-
var markdownExts = ['.md', '.markdown'];
5+
var markdownExts = ['.md', '.markdown', '.mdx'];
66
var ignoredDirs = ['.', '..', '.git', 'node_modules'];
77

88
function separateFilesAndDirs(fileInfos) {

lib/transform.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,29 @@ var _ = require('underscore')
66
, getHtmlHeaders = require('./get-html-headers')
77
, md = require('@textlint/markdown-to-ast');
88

9-
var start = '<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n' +
10-
'<!-- DON\'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->'
11-
, end = '<!-- END doctoc generated TOC please keep comment here to allow auto update -->'
12-
, skipTag = '<!-- DOCTOC SKIP -->';
9+
var commentTypes = {
10+
md: {
11+
start: "<!--",
12+
end: "-->",
13+
escapedStart: "<!--",
14+
},
15+
mdx: {
16+
start: "{/*",
17+
end: "*/}",
18+
escapedStart: "{\/\\*",
19+
}
20+
}
1321

22+
var { start: startMd , end: endMd } = generateComments("md")
23+
24+
var commentEscapedStart = commentTypes.md.escapedStart
1425

1526
function matchesStart(line) {
16-
return (/<!-- START doctoc /).test(line);
27+
return new RegExp(`${commentEscapedStart} START doctoc `).test(line);
1728
}
1829

1930
function matchesEnd(line) {
20-
return (/<!-- END doctoc /).test(line);
31+
return new RegExp(`${commentEscapedStart} END doctoc `).test(line);
2132
}
2233

2334
function notNull(x) { return x !== null; }
@@ -31,6 +42,17 @@ function isString(y) {
3142
return typeof y === 'string';
3243
}
3344

45+
function generateComments(syntax){
46+
var commentStart = commentTypes[syntax]?.start || commentTypes.md.start
47+
, commentEnd = commentTypes[syntax]?.end || commentTypes.md.end
48+
49+
var start = `${commentStart} START doctoc generated TOC please keep comment here to allow auto update ${commentEnd}\n` +
50+
`${commentStart} DON\'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE ${commentEnd}`
51+
, end = `${commentStart} END doctoc generated TOC please keep comment here to allow auto update ${commentEnd}`
52+
, skipTag = `${commentStart} DOCTOC SKIP ${commentEnd}`;
53+
54+
return { start, end, skipTag}
55+
}
3456

3557
function getMarkdownHeaders (lines, maxHeaderLevel) {
3658
function extractText (header) {
@@ -108,12 +130,18 @@ function determineTitle(title, notitle, lines, info) {
108130
return info.hasStart ? lines[info.startIdx + 2] : defaultTitle;
109131
}
110132

111-
exports = module.exports = function transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly) {
133+
exports = module.exports = function transform(content, mode, maxHeaderLevel, title, notitle, entryPrefix, processAll, updateOnly, syntax) {
134+
syntax = syntax || "md"
135+
const { skipTag, start, end } = generateComments(syntax)
136+
112137
if (content.indexOf(skipTag) !== -1) return { transformed: false };
113138

114139
mode = mode || 'github.com';
115140
entryPrefix = entryPrefix || '-';
116141

142+
// update it for matchesStart and matchesEnd
143+
commentEscapedStart = commentTypes[syntax]?.escapedStart || commentTypes.md.escapedStart
144+
117145
// only limit *HTML* headings by default
118146
var maxHeaderLevelHtml = maxHeaderLevel || 4;
119147

@@ -168,5 +196,5 @@ exports = module.exports = function transform(content, mode, maxHeaderLevel, tit
168196
return { transformed : true, data : data, toc: toc, wrappedToc: wrappedToc };
169197
};
170198

171-
exports.start = start;
172-
exports.end = end;
199+
exports.start = startMd;
200+
exports.end = endMd;

0 commit comments

Comments
 (0)