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

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

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

我知道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的文件。

其他回答

您还可以使用pandoc,它是将“一种标记格式转换为另一种标记格式”的“瑞士军刀”。如果您提供——toc参数,它可以在输出文档中自动生成一个内容表。

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

示例shell命令行:

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

有一个Ruby脚本叫做mdtoc。rb可以自动生成一个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)

请参阅我关于这个主题的博客文章。

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

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

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

嗯…使用Markdown的标题!?

那就是:

#这相当于< h1 >

这相当于< h2>

这相当于< h3>

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

希望有帮助!

--JF

你可以在第一行使用[TOC],然后在底部,你唯一需要做的就是确保标题使用相同的大字体。 目录会自动出来。(但这只出现在一些markdown编辑器,我没有尝试所有)