Markdown创建页面和目录?

我开始使用标记来做笔记。

我使用标志着来查看我的笔记,它很漂亮。

但是随着我的笔记变长,我发现很难找到我想要的东西。

我知道markdown可以创建表,但它是否能够创建目录,跳转到部分,或定义页面部分markdown?

或者,是否有降价阅读器/编辑器可以做这些事情。搜索也是一个不错的功能。

简而言之,我想让它成为我很棒的笔记工具,功能就像写一本书一样。

584033 次浏览

MultiMarkdown作曲家似乎生成了一个目录来辅助编辑。

也可能存在一个或另一个库,它们可以生成toc:参见Python Markdown TOC扩展

我刚刚为python-markdown编写了一个扩展,它使用它的解析器来检索标题,并将TOC输出为带有本地链接的markdown格式的无序列表。文件是

... 它应该放在markdown安装的markdown/extensions/目录下。然后,你所要做的,就是输入锚<a>标签和id="..."属性作为参考-对于这样的输入文本:

$ cat test.md
Hello
=====


## <a id="sect one"></a>SECTION ONE ##


something here


### <a id='sect two'>eh</a>SECTION TWO ###


something else


#### SECTION THREE


nothing here


### <a id="four"></a>SECTION FOUR


also...

... 扩展可以这样调用:

$ python -m markdown -x md_toc test.md
* Hello
* [SECTION ONE](#sect one)
* [SECTION TWO](#sect two)
* SECTION THREE
* [SECTION FOUR](#four)

... 然后您可以将这个toc粘贴回您的标记文档中(或者在您的文本编辑器中有一个快捷方式,在当前打开的文档上调用脚本,然后将结果toc插入到同一文档中)。

请注意,python-markdown的旧版本没有__main__.py模块,因此,上面的命令行调用将不适用于这些版本。

嗯…使用Markdown的标题!?

那就是:

#这相当于<h1 >

##这相当于<h2 >

###这相当于<h3 >

许多编辑器会向您展示TOC。您还可以为标题标记提供grep,并创建自己的标题标记。

希望有帮助!

——摩根富林明

您可以尝试这个ruby脚本从一个降价文件生成TOC。

 #!/usr/bin/env ruby


require 'uri'


fileName = ARGV[0]
fileName = "README.md" if !fileName


File.open(fileName, 'r') do |f|
inside_code_snippet = false
f.each_line do |line|
forbidden_words = ['Table of contents', 'define', 'pragma']
inside_code_snippet = !inside_code_snippet if line.start_with?('```')
next if !line.start_with?("#") || forbidden_words.any? { |w| line =~ /#{w}/ } || inside_code_snippet


title = line.gsub("#", "").strip
href = URI::encode title.gsub(" ", "-").downcase
puts "  " * (line.count("#")-1) + "* [#{title}](\##{href})"
end
end

根据您的工作流,您可能需要查看捷联式

这是原始版本(http://strapdownjs.com)的一个分支,它添加了目录的生成。

在repo上有一个apache配置文件(可能还没有正确更新)来包装简单的markdown,如果你不喜欢写在html文件中。

我只是开始做同样的事情(在Markdown做笔记)。我使用Sublime Text 2和MarkdownPreview插件。内置的降价解析器支持[TOC]

你可以试一试。

# Table of Contents
1. [Example](#example)
2. [Example2](#example2)
3. [Third Example](#third-example)
4. [Fourth Example](#fourth-examplehttpwwwfourthexamplecom)




## Example
## Example2
## Third Example
## [Fourth Example](http://www.fourthexample.com)

有两种方法可以在标记文档中创建TOC(摘要)。

1. 手动

# My Table of content
- [Section 1](#id-section1)
- [Section 2](#id-section2)


<div id='id-section1'/>
## Section 1
<div id='id-section2'/>
## Section 2

2. 以编程方式

你可以使用例如一个脚本,生成摘要为您,看看我的项目在github - < a href = " https://github.com/velthune/summarizeMD " > summarizeMD < / > -

我也尝试过其他脚本/npm模块(例如doctoc),但没有人用工作锚重现TOC。

我写了一个python脚本,解析一个降价文件,并输出一个目录作为降价列表:md-to-toc

与我发现的其他脚本不同,md-to-toc正确地支持重复的标题。它也不需要互联网连接,所以它可以在任何md文件,而不仅仅是从公共回购。

这里有一个有用的方法。应该在任何MarkDown编辑器中产生可点击的引用。

# Table of contents
1. [Introduction](#introduction)
2. [Some paragraph](#paragraph1)
1. [Sub paragraph](#subparagraph1)
3. [Another paragraph](#paragraph2)


## This is the introduction <a name="introduction"></a>
Some introduction text, formatted in heading 2 style


## Some paragraph <a name="paragraph1"></a>
The first paragraph text


### Sub paragraph <a name="subparagraph1"></a>
This is a sub paragraph, formatted in heading 3 style


## Another paragraph <a name="paragraph2"></a>
The second paragraph text

生产:

目录

  1. 介绍< a href = " https://stackoverflow.com/questions/11948245/markdown-to-create-pages-and-table-of-contents/33433098 " > < / >介绍
  2. 某些段落
    1. 子段落 .
    2. 李< / ol > < / >
    3. 另一段 .

    这是介绍

    一些介绍文本,格式为标题2的风格

    一些段落

    第一段文字

    子段

    这是一个子段落,格式为标题3

    另一个段落

    第二段文字

基于albertodebortoli answer创建了附加检查和标点符号替换功能。

# @fn       def generate_table_of_contents markdown # \{\{{
# @brief    Generates table of contents for given markdown text
#
# @param    [String]  markdown Markdown string e.g. File.read('README.md')
#
# @return   [String]  Table of content in markdown format.
#
def generate_table_of_contents markdown
table_of_contents = ""
i_section = 0
# to track markdown code sections, because e.g. ruby comments also start with #
inside_code_section = false
markdown.each_line do |line|
inside_code_section = !inside_code_section if line.start_with?('```')


forbidden_words = ['Table of contents', 'define', 'pragma']
next if !line.start_with?('#') || inside_code_section || forbidden_words.any? { |w| line =~ /#{w}/ }


title = line.gsub("#", "").strip
href = title.gsub(/(^[!.?:\(\)]+|[!.?:\(\)]+$)/, '').gsub(/[!.,?:; \(\)-]+/, "-").downcase


bullet = line.count("#") > 1 ? " *" : "#{i_section += 1}."
table_of_contents << "  " * (line.count("#") - 1) + "#{bullet} [#{title}](\##{href})\n"
end
table_of_contents
end

为了让我们在原子中制作README.md文件(我是如何找到这个线程的):

apm install markdown-toc

< a href = " https://atom。io /包/ markdown-toc noreferrer“rel = > https://atom.io/packages/markdown-toc < / >

Typora通过在文档中添加[TOC]生成目录

由不同Markdown解析器生成的锚标记是不相等的。

如果你正在使用Markdown解析器GFM (GitHub调味Markdown)或Redcarpet,我写了一个Vim插件来处理目录。

特性

  1. 生成Markdown文件目录。

    支持的Markdown解析器:

    • GFM (GitHub调味Markdown)
    • Redcarpet
    • 李< / ul > < / >
    • 更新现有的目录。

    • 自动更新现有的目录保存。

截图

vim-markdown-toc

使用

生成目录

将光标移动到要添加目录的行,然后在下面键入适合您的命令。该命令将在光标进入目录后生成标题。

  1. < p > # EYZ0

    生成GFM链接样式的目录。

    此命令适用于GitHub存储库中的Markdown文件,如README。

    . md和GitBook的Markdown文件
  2. < p > # EYZ0

    生成红地毯链接样式的目录。

    这个命令适用于Jekyll或任何其他使用Redcarpet作为Markdown解析器的地方。

    你可以查看在这里来了解GFM和Redcarpet风格toc链接的区别

手动更新现有的目录

通常你不需要这样做,现有的目录将自动更新保存默认情况下。如果您想手动执行,只需使用:UpdateToc命令。

下载和文档

https://github.com/mzlogin/vim-markdown-toc

我不确定,什么是降价的官方文件。 交叉引用可以只写在括号[Heading]中,或者用空括号[Heading][]

都使用pandoc工作。 所以我创建了一个快速bash脚本,这将取代$__TOC__在md文件与其TOC。(你需要envsubst,它可能不是你发行版的一部分)

#!/bin/bash
filename=$1
__TOC__=$(grep "^##" $filename | sed -e 's/ /1. /;s/^##//;s/#/   /g;s/\. \(.*\)$/. [\1][]/')
export __TOC__
envsubst '$__TOC__' < $filename

MultiMarkdown 4.7有一个\{\{TOC}}宏,用于插入一个目录表。

如果你碰巧使用Eclipse,你可以使用Ctrl+O(大纲)快捷方式,这将显示等价的目录,并允许在节标题中搜索(自动完成)。

您也可以打开大纲视图(窗口->显示视图->大纲),但它没有自动完成搜索。

你也可以使用pandoc“瑞士军队knife"用于将“一种标记格式转换为另一种”;。如果您提供了--toc参数,它可以在输出文档中自动生成一个内容表。

提示: --toc需要-s(生成一个独立的文档),否则将不会生成目录。

示例shell命令行:

./pandoc -s --toc input.md -o output.md

对于Visual Studio代码用户来说,今天(2020)使用的最佳选择是Markdown All in One插件(扩展)。

要安装它,启动VS Code快速打开(控制/⌘+P),粘贴以下命令,并按enter。

ext install yzhang.markdown-all-in-one

为了生成TOC,打开命令面板(控制/⌘+转变+P)并选择# eyz0选项。


另一个选择是减价TOC插件。

要安装它,启动VS Code快速打开(控制/⌘+P),粘贴以下命令,并按enter。

ext install markdown-toc

为了生成TOC,打开命令面板(控制/⌘+转变+P)并选择Markdown TOC:Insert/Update选项或使用控制/⌘+T

# Table of Contents
1. [Example](#example)
2. [Example2](#example2)
3. [Third Example](#third-example)


## Example [](#){name=example}
## Example2 [](#){name=example2}
## [Third Example](#){name=third-example}
如果你使用markdown extra,不要忘记你可以为链接、标题、代码围栏和图像添加特殊属性 # EYZ0 < / p >
你可以在第一行和底部使用[TOC],你唯一需要做的就是确保标题使用相同的大字体。 目录会自动出来。(但这只出现在一些降价编辑器,我没有尝试所有)

您可以使用这个bash一行程序生成它。假设您的降价文件名为FILE.md

echo "## Contents" ; echo ;
cat FILE.md | grep '^## ' | grep -v Contents | sed 's/^## //' |
while read -r title ; do
link=$(echo $title | tr 'A-Z ' 'a-z-') ;
echo "- [$title](#$link)" ;
done

使用toc.py,这是一个小的python脚本,它为你的markdown生成一个目录。

用法:

  • 在你的Markdown文件中,在你想放置目录的地方添加<toc>
  • $python toc.py README.md(使用你的markdown文件名而不是README.md)

干杯!

有一个名为mdtoc.rb的Ruby脚本可以自动生成一个GFM Markdown目录,它与本文发布的其他一些脚本类似,但略有不同。

给定一个输入Markdown文件如下:

# Lorem Ipsum


Lorem ipsum dolor sit amet, mei alienum adipiscing te, has no possit delicata. Te nominavi suavitate sed, quis alia cum no, has an malis dictas explicari. At mel nonumes eloquentiam, eos ea dicat nullam. Sed eirmod gubergren scripserit ne, mei timeam nonumes te. Qui ut tale sonet consul, vix integre oportere an. Duis ullum at ius.


## Et cum


Et cum affert dolorem habemus. Sale malis at mel. Te pri copiosae hendrerit. Cu nec agam iracundia necessitatibus, tibique corpora adipisci qui cu. Et vix causae consetetur deterruisset, ius ea inermis quaerendum.


### His ut


His ut feugait consectetuer, id mollis nominati has, in usu insolens tractatos. Nemore viderer torquatos qui ei, corpora adipiscing ex nec. Debet vivendum ne nec, ipsum zril choro ex sed. Doming probatus euripidis vim cu, habeo apeirian et nec. Ludus pertinacia an pro, in accusam menandri reformidans nam, sed in tantas semper impedit.


### Doctus voluptua


Doctus voluptua his eu, cu ius mazim invidunt incorrupte. Ad maiorum sensibus mea. Eius posse sonet no vim, te paulo postulant salutatus ius, augue persequeris eum cu. Pro omnesque salutandi evertitur ea, an mea fugit gloriatur. Pro ne menandri intellegam, in vis clita recusabo sensibus. Usu atqui scaevola an.


## Id scripta


Id scripta alterum pri, nam audiam labitur reprehendunt at. No alia putent est. Eos diam bonorum oportere ad. Sit ad admodum constituto, vide democritum id eum. Ex singulis laboramus vis, ius no minim libris deleniti, euismod sadipscing vix id.

它生成了这个目录:

$ mdtoc.rb FILE.md
#### Table of contents


1. [Et cum](#et-cum)
* [His ut](#his-ut)
* [Doctus voluptua](#doctus-voluptua)
2. [Id scripta](#id-scripta)

也可以参考我关于这个话题的博客帖子

只需要增加幻灯片的数量!它与markdown ioslides和revealjs演示一起工作

## Table of Contents


1. [introduction](#3)
2. [section one](#5)

我使用了https://github.com/ekalinin/github-markdown-toc,它提供了一个命令行实用程序,可以从一个降价文档自动生成目录。

没有插件、宏或其他依赖项。安装实用程序后,只需将实用程序的输出粘贴到文档中需要目录的位置。使用起来非常简单。

$ cat README.md | ./gh-md-toc -

对我来说,@Tum提出的解决方案对于2个层次的目录来说非常有效。然而,对于第3个关卡,这种方法却不起作用。它没有像前两关那样显示链接,而是显示纯文本3.5.1. [bla bla bla](#blablabla) <br>

我的解决方案是@Tum解决方案(非常简单)的补充,适用于需要3级或以上目录的人。

在第二层,一个简单的制表符将为您正确地完成缩进。但它不支持2个标签。相反,你必须使用一个选项卡,并根据自己的需要添加尽可能多的&nbsp;,以便正确对齐第三个关卡。

下面是一个使用4个关卡的例子(关卡越高,它就变得越糟糕):

# Table of Contents
1. [Title](#title) <br>
1.1. [sub-title](#sub_title) <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.1.1. [sub-sub-title](#sub_sub_title)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.1.1.1. [sub-sub-sub-title](#sub_sub_sub_title)


# Title <a name="title"></a>
Heading 1


## Sub-Title <a name="sub_title"></a>
Heading 2


### Sub-Sub-Title <a name="sub_sub_title"></a>
Heading 3


#### Sub-Sub-Sub-Title <a name="sub_sub_sub_title"></a>
Heading 4

这将给出以下结果,其中目录表的每个元素都是到其相应部分的链接。还要注意<br>,以便添加新行,而不是在同一行上。

目录

    <李>标题< br > 1.1. 字幕< br > ,,,,, 1.1.1。Sub-Sub-Title < br > ,,,,,,,,,,,,,,, 1.1.1.1。李Sub-Sub-Sub-Title < / >

标题

标题1

字幕

标题2

Sub-Sub-Title

标题3

Sub-Sub-Sub-Title

标题4

在Gitlab上,markdown支持:[[_TOC_]]

如果你的Markdown文件要在bitbucket.org上的回购中显示,你应该在你想要你的目录的位置添加[TOC]。然后它将自动生成。更多信息:

https://confluence.atlassian.com/bitbucket/add-a-table-of-contents-to-a-wiki-221451163.html

在Visual Studio Code (VSCode)中,你可以使用Markdown All in One扩展名。

安装完成后,请按照以下步骤操作:

  1. 按# EYZ0 + # EYZ1 + # EYZ2
  2. 选择# EYZ0

编辑:现在我使用DocToc来生成目录,详见我的另一个答案

下面是一个简短的PHP代码,我用来生成TOC,并用锚丰富任何标题:

$toc = []; //initialize the toc to an empty array
$markdown = "... your mardown content here...";


$markdown = preg_replace_callback("/(#+)\s*([^\n]+)/",function($matches) use (&$toc){
static $section = [];
$h = strlen($matches[1]);


@$section[$h-1]++;
$i = $h;
while(isset($section[$i])) unset($section[$i++]);


$anchor = preg_replace('/\s+/','-', strtolower(trim($matches[2])));


$toc[] = str_repeat('  ',$h-1)."* [".implode('.',$section).". {$matches[2]}](#$anchor)";
return str_repeat('#',$h)." <strong>".implode('.',$section).".</strong> ".$matches[2]."\n<a name=\"$anchor\"></a>\n";
}, $markdown);

然后你可以打印经过处理的markdown和toc:

   print(implode("\n",$toc));
print("\n\n");
print($markdown);

只需使用带有插件的文本编辑器。

您的编辑器很可能有包/插件来为您处理这个问题。例如,在Emacs中,您可以安装markdown-toc TOC生成器。然后在编辑时,重复调用M-x markdown-toc-generate-or-refresh-toc。如果你想经常这样做,那就值得一个键绑定。它擅长生成一个简单的TOC,而不会用HTML锚污染您的文档。

其他编辑器也有类似的插件,所以流行的列表是这样的:

  • # EYZ0: # EYZ1
  • # EYZ0: # EYZ1
  • # EYZ0: # EYZ1
  • # EYZ0: # EYZ1

正如在其他回答中提到的,有多种方法可以自动生成目录。大多数都是开源软件,可以根据您的需要进行调整。

然而,我所缺少的是,使用Markdown提供的有限选项,在视觉上吸引人的目录格式。我们得出了以下结论:

代码

## Content


**[1. Markdown](#heading--1)**


* [1.1. Markdown formatting cheatsheet](#heading--1-1)
* [1.2. Markdown formatting details](#heading--1-2)


**[2. BBCode formatting](#heading--2)**


* [2.1. Basic text formatting](#heading--2-1)


* [2.1.1. Not so basic text formatting](#heading--2-1-1)


* [2.2. Lists, Images, Code](#heading--2-2)
* [2.3. Special features](#heading--2-3)


----

在你的文档中,你可以像这样放置目标子部分标记:

<div id="heading--1-1"/>
### 1.1. Markdown formatting cheatsheet

根据你在哪里以及如何使用Markdown,以下也应该工作,并提供了更好看Markdown代码:

### 1.1. Markdown formatting cheatsheet <a name="heading--1-1"/>

例子呈现

内容

减价< / >

BBCode格式化< / >

优势

  • 您可以根据需要添加任意级别的章节和子章节。在目录中,这些将在更深层次上显示为嵌套的无序列表。

  • 不使用有序列表。这些将创建缩进,不会链接数字,并且不能用于创建像“1.1.”这样的十进分类编号。

  • 第一关不使用列表。在这里,使用无序列表是可能的,但不是必要的:缩进和项目符号只会增加视觉上的混乱,在这里没有任何功能,所以我们在第一个ToC关卡中根本没有使用列表。

  • 通过粗体打印在内容表中的第一级部分进行视觉强调。

  • 短的、有意义的子部分标记,在浏览器的URL栏中看起来“漂亮”,比如#heading--1-1,而不是包含实际标题的转换片段的标记。

  • 该代码使用H2标题(## …)的部分,H3标题(### …)的子标题等。这使得源代码更容易阅读,因为与以H1标题(# …)开头的部分相比,## …在滚动时提供了更强的视觉线索。当您为文档标题本身使用H1标题时,它在逻辑上仍然是一致的。

  • 最后,我们添加了一个很好的水平规则来分离目录和实际内容。

要了解更多关于这个技术以及我们如何在论坛软件话语在这里看到的中使用它。

你可以使用DocToc从命令行生成目录:

doctoc /path/to/file

要使链接与Bitbucket生成的锚点兼容,请使用--bitbucket参数运行它。

如果使用Sublime文本编辑器MarkdownTOC插件工作得很漂亮!看到的:

  1. < a href = " https://packagecontrol。io/packages/MarkdownTOC" rel="nofollow noreferrer">https://packagecontrol.io/packages/MarkdownTOC .io/packages/MarkdownTOC " rel="nofollow noreferrer">https://packagecontrol.io/packages/MarkdownTOC
  2. https://github.com/naokazuterada/MarkdownTOC

安装完成后,点击首选项>包设置—>MarkdownTOC——比;设置—用户,用于自定义设置。下面是你可以选择的选项:https://github.com/naokazuterada/MarkdownTOC#configuration

我的建议如下:

{
"defaults": {
"autoanchor": true,
"autolink": true,
"bracket": "round",
"levels": [1,2,3,4,5,6],
"indent": "\t",
"remove_image": true,
"link_prefix": "",
"bullets": ["-"],
"lowercase": "only_ascii",
"style": "ordered",
"uri_encoding": true,
"markdown_preview": ""
},
"id_replacements": [
{
"pattern": "\\s+",
"replacement": "-"
},
{
"pattern": "&lt;|&gt;|&amp;|&apos;|&quot;|&#60;|&#62;|&#38;|&#39;|&#34;|!|#|$|&|'|\\(|\\)|\\*|\\+|,|/|:|;|=|\\?|@|\\[|\\]|`|\"|\\.|\\\\|<|>|{|}|™|®|©|%",
"replacement": ""
}
],
"logging": false
}

要插入目录,只需单击文档顶部想要插入目录的位置,然后转到Tools—>降价TOC—>插入目录。

它将插入如下内容:

<!-- MarkdownTOC -->


1. [Helpful Links:](#helpful-links)
1. [Sublime Text Settings:](#sublime-text-settings)
1. [Packages to install](#packages-to-install)


<!-- /MarkdownTOC -->

注意它为您插入的<!-- --> HTML注释。这些是特殊的标记,帮助程序知道ToC在哪里,所以,保持这些完整。

为了更花哨,添加一些<details><summary> HTML标签,使ToC可折叠/展开,如下所示:

<details>
<summary><b>Table of Contents</b> (click to open)</summary>
<!-- MarkdownTOC -->


1. [Helpful Links:](#helpful-links)
1. [Sublime Text Settings:](#sublime-text-settings)
1. [Packages to install](#packages-to-install)


<!-- /MarkdownTOC -->
</details>

现在,你得到了这个超级酷的效果,如下图所示。在main eRCaGuy_dotfiles readme在这里Sublime_Text_editor readme中可以看到它的作用。

    <李>崩溃: 李# EYZ0 < / > <李>扩展: 李# EYZ0 < / >

有关它的使用和限制的额外信息,请务必阅读我对的自述MarkdownTOC插件的注释。

下面是一个生成目录的简单bash脚本。不需要特殊的依赖项,而是bash

https://github.com/Lirt/markdown-toc-bash

它可以很好地处理标题内的特殊符号,标记标题中的链接和忽略代码块。

我使用这个网站Markdown-TOC创造者,有些人可以粘贴他的整个markdown条目,网站会自动创建所有必需的标签和TOC(内容表),所以一些人可以很容易地复制粘贴到他自己的文档中。

作为手工制作链接列表的另一种选择,让我们概述所有可用的开箱即用解决方案来插入一个目录(请评论和扩展以保持最新):

使用咕噜v5, markdown支持:

<!-- assure you have a blank line before -->
[[_TOC_]]

这也适用于Azure DevOps wiki


由于Gitlab切换了从Redcarpet到Kramdown的降价引擎,它们现在支持以下语法

- TOC
{:toc}

看到# EYZ0


MultiMarkdown as of 4.7有一个以下宏:

\{\{TOC}}

根据Jannik的回答:
如果你的Markdown文件要显示在bitbucket.org上的回购中,你可以在你想要你的目录(更多信息在这里)的位置使用以下命令:

[TOC]

根据保罗·尤尔扎克的回答:
当您在文档中写入[TOC]时,Markdown编辑器Typora .也会生成一个目录


我知道,我的回答有点晚了。然而,我自己却错过了这样一个概述。我的编辑尼古拉斯·特里的回答扩展到一个概述被拒绝了。

这是一个小的nodejs脚本,它生成目录并考虑重复的标题:

const fs = require('fs')
const { mdToPdf } = require('md-to-pdf');


const stringtoreplace = '<toc/>'


const processTitleRepetitions = (contents, titleMap) => {
for (const content of contents) {
titleMap[content.link] = typeof titleMap[content.link] === 'undefined'
? 0
: titleMap[content.link] + 1
if (titleMap[content.link] > 0) {
content.link = `${content.link}-${titleMap[content.link]}`
}
}
}


const convertContentToPdf = async (targetFile) => {
const pdf = await mdToPdf({path: targetFile}).catch(console.error)
if(pdf) {
const pdfFile = `${targetFile.replace(/\.md/, '')}.pdf`
fs.writeFileSync(pdfFile, pdf.content)
return pdfFile
}
throw new Error("PDF generation failed.")
}


const generateTOC = (file, targetFile) => {
// Extract headers
const fileContent = fs.readFileSync(file, 'utf-8')
const titleLine = /((?<=^)#+)\s(.+)/
const contents = fileContent.split(/\r?\n/).
map(line => line.match(titleLine)).
filter(match => match).
filter(match => match[1].length > 1).
map(regExpMatchArray => {
return {
level: regExpMatchArray[1].length, text: regExpMatchArray[2],
link: '#' + regExpMatchArray[2].replace(/(\s+|[.,\/#!$%^&*;:{}=\-_`~()]+)/g, '-').toLowerCase(),
}
})
const titleMap = {}
processTitleRepetitions(contents, titleMap)
// Write content
let toctext = '## Table of Contents\n'
// Find the toplevel to adjust the level of the table of contents.
const topLevel = contents.reduce((maxLevel, content) => Math.min(content['level'], maxLevel), 1000)
levelCounter = {}
contents.forEach(item => {
let currentLevel = parseInt(item.level)
levelCounter[currentLevel] = levelCounter[currentLevel] ? levelCounter[currentLevel] + 1 : 1
Object.entries(levelCounter).forEach(e => {
if(currentLevel < parseInt(e[0])) {
levelCounter[e[0]] = 0
}
})
const level = Array(currentLevel - topLevel).fill('\t').join('')
const text = `${levelCounter[currentLevel]}. [${item['text']}](${item['link']}) \n`
toctext += level + text
})


const updatedContent = fileContent.toString().replace(stringtoreplace, toctext)
fs.writeFileSync(targetFile, updatedContent)
convertContentToPdf(targetFile).then((pdfFile) => {
console.info(`${pdfFile} has been generated.`)
})
}


const args = process.argv.slice(2)


if(args.length < 2) {
console.error("Please provide the name of the markdown file from which the headers should be extracted and the name of the file with the new table of contents")
console.info("Example: node MD_TOC.js <source_md> <target_md>")
process.exit(1)
}


const source_md = args[0]
const target_md = args[1]


generateTOC(source_md, target_md)

要使用它,你需要在markdown文件中注入<toc/>

下面是你如何使用它:

generateTOC('../README.md', '../README_toc.md')

第一个参数是源markdown文件,第二个参数是带有markdown的文件。

如果你使用折扣 markdown,启用标记-ftoc来自动生成,并使用-T来前置一个目录表,例如:

markdown -T -ftoc <<EOT
#heading 1


content 1


##heading 2


content 2
EOT

将会产生

<ul>
<li><a href="#heading-1">heading 1</a>
<ul>
<li><a href="#heading-2">heading 2</a></li>
</ul>
</li>
</ul>
<a name="heading-1"></a>
<h1>heading 1</h1>
...

显然,你也可以使用markdown -toc,其中man没有提到,但USAGE信息(由非法选项如markdown -h触发)。


我花了一段时间阅读源代码才明白这一点,所以我把它写下来主要是为了未来的我。我在Arch Linux上使用折扣markdown,从discount包。man并没有真正告诉你它是折扣,但在AUTHOR下面提到了大卫·帕森斯。

markdown --version
# markdown: discount 2.2.7

如果IntelliJ用户 do:, command ncontrol n提供了创建或更新目录的选项。参考:# EYZ3