我开始使用标记来做笔记。
我用标记来查看我的笔记,它很漂亮。
但是随着我的笔记变长,我发现很难找到我想要的东西。
我知道markdown可以创建表,但它是否能够创建目录,跳转到部分,或定义页面部分markdown?
或者,是否有降价阅读器/编辑器可以做这些事情。搜索也是一个不错的功能。
简而言之,我想让它成为我很棒的笔记工具,功能就像写一本书一样。
我开始使用标记来做笔记。
我用标记来查看我的笔记,它很漂亮。
但是随着我的笔记变长,我发现很难找到我想要的东西。
我知道markdown可以创建表,但它是否能够创建目录,跳转到部分,或定义页面部分markdown?
或者,是否有降价阅读器/编辑器可以做这些事情。搜索也是一个不错的功能。
简而言之,我想让它成为我很棒的笔记工具,功能就像写一本书一样。
当前回答
这是一个小的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的文件。
其他回答
MultiMarkdown 4.7有一个{{TOC}}宏,用于插入一个目录表。
基于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
你可以试一试。
# 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)
如果使用Sublime文本编辑器,MarkdownTOC插件工作得很漂亮!看到的:
https://packagecontrol.io/packages/MarkdownTOC https://github.com/naokazuterada/MarkdownTOC
安装完成后,点击Preferences—> Package Settings—> MarkdownTOC—> Settings—User,自定义设置。以下是你可以选择的选项: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": "<|>|&|'|"|<|>|&|'|"|!|#|$|&|'|\\(|\\)|\\*|\\+|,|/|:|;|=|\\?|@|\\[|\\]|`|\"|\\.|\\\\|<|>|{|}|™|®|©|%",
"replacement": ""
}
],
"logging": false
}
要插入目录,只需单击文档顶部想要插入目录的位置,然后转到工具—> Markdown TOC—> insert 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>
现在,你得到了这个超级酷的效果,如下图所示。在我的eRCaGuy_dotfiles主自述文件中看到它的作用,或者在我的Sublime_Text_editor自述文件中看到它的作用。
崩溃: 扩展:
有关它的使用和限制的额外信息,请务必阅读我在自述书中对MarkdownTOC插件的注释。
我刚刚为python-markdown编写了一个扩展,它使用它的解析器来检索标题,并将TOC输出为带有本地链接的markdown格式的无序列表。文件是
Md_toc.py(是Md_toc.py)
... 它应该放在markdown安装的markdown/extensions/目录中。然后,你所要做的就是输入anchor <a> tags,带一个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模块,因此,上面的命令行调用将不适用于这些版本。