我开始使用标记来做笔记。
我用标记来查看我的笔记,它很漂亮。
但是随着我的笔记变长,我发现很难找到我想要的东西。
我知道markdown可以创建表,但它是否能够创建目录,跳转到部分,或定义页面部分markdown?
或者,是否有降价阅读器/编辑器可以做这些事情。搜索也是一个不错的功能。
简而言之,我想让它成为我很棒的笔记工具,功能就像写一本书一样。
我开始使用标记来做笔记。
我用标记来查看我的笔记,它很漂亮。
但是随着我的笔记变长,我发现很难找到我想要的东西。
我知道markdown可以创建表,但它是否能够创建目录,跳转到部分,或定义页面部分markdown?
或者,是否有降价阅读器/编辑器可以做这些事情。搜索也是一个不错的功能。
简而言之,我想让它成为我很棒的笔记工具,功能就像写一本书一样。
当前回答
作为手工制作链接列表的替代方案,让我们概述所有可用的开箱即用的解决方案来插入目录(请评论和扩展以保持最新):
在咕噜5版本中,markdown支持这一点:
<!-- assure you have a blank line before -->
[[_TOC_]]
这也适用于Azure DevOps wiki。
由于Gitlab将降价引擎从Redcarpet切换到Kramdown,他们现在支持以下语法
- TOC
{:toc}
看到https://about.gitlab.com/handbook/markdown-guide/ table-of-contents-toc
MultiMarkdown在4.7有一个下面的宏:
{{TOC}}
根据Jannik的回答: 如果你的Markdown文件是显示在bitbucket.org上的回购,你可以在你想要你的目录(更多信息在这里)的位置使用以下:
[TOC]
根据Paul Jurczak的回答: 当您在文档中写入[TOC]时,Markdown编辑器Typora也会生成一个目录。
我知道,我的回答有点晚了。然而,我自己却错过了这样一个概述。我对尼古拉斯·特里的回答进行了编辑,将其扩展为概述,但被拒绝了。
其他回答
MultiMarkdown Composer似乎生成了一个目录来辅助编辑。
也可能存在这样或那样的库,它们可以生成TOC:参见Python Markdown 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
使用toc.py,这是一个小的python脚本,它为你的markdown生成一个目录。
用法:
在Markdown文件中,将<toc>添加到您希望放置目录的位置。 $python toc.py README。md(使用您的markdown文件名而不是README.md)
干杯!
只需使用带有插件的文本编辑器。
你的编辑器很可能有一个包/插件来为你处理这个问题。例如,在Emacs中,可以安装markdown-toc TOC生成器。然后在编辑时,只需反复调用M-x markdown-toc-generate-or-refresh-toc。如果你想经常这样做,那就值得一个键绑定。它擅长生成一个简单的TOC,而不会用HTML锚污染您的文档。
其他编辑器也有类似的插件,所以流行的列表是这样的:
器name: markdown-toc Vim: markdown-toc Atom: markdown-toc VSCode: markdown-toc
这是一个小的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的文件。