使用asciidoc.js从解析文档获取AsciiDoc源码的技术问题
获取AsciiDoc章节的原始代码或从AST重新生成
你遇到的问题是因为getContent()方法默认会返回渲染后的HTML内容,而不是原始的AsciiDoc代码——毕竟asciidoctor.js的核心设计是将AsciiDoc转换为HTML。不过有两种可靠的方法可以解决你的需求:
方法1:利用行号截取原始AsciiDoc代码
asciidoctor.js解析后的章节节点(Section)包含了该章节在原始文件中的起始和结束行号,你可以通过这些信息直接从原文件中截取对应的代码片段。具体步骤如下:
- 先读取原始AsciiDoc文件的全部内容
- 通过章节节点的
getStartLine()和getEndLine()获取行范围 - 截取对应行的内容并拼接
修改你的代码如下:
const asciidoctor = require("asciidoctor.js")(); const fs = require("fs"); const path = require("path"); // 读取原始文件内容 const docPath = "../user-manual/src/main/asciidoc/Changelog.adoc"; const rawContent = fs.readFileSync(docPath, "utf8"); const rawLines = rawContent.split("\n"); const changelogDoc = asciidoctor.loadFile(docPath); for (const sec of changelogDoc.getSections()) { for (const subsec of sec.getSections()) { for (const subsubsec of subsec.getSections()) { if (subsubsec.hasTitle()) { const key = subsubsec.getTitle().match(/X[A-Z]+-[0-9]+/); if (key) { // 获取行号(注意:asciidoctor的行号从1开始,数组索引从0开始) const startLine = subsubsec.getStartLine() - 1; const endLine = subsubsec.getEndLine() - 1; // 截取原始AsciiDoc代码 const sectionRawAsciidoc = rawLines.slice(startLine, endLine + 1).join("\n"); console.log(sectionRawAsciidoc); // 这里可以写入新文件 // fs.writeFileSync("target-section.adoc", sectionRawAsciidoc); return sectionRawAsciidoc; } } } } }
方法2:从AST重新生成AsciiDoc(适合新版asciidoctor.js)
如果你能将asciidoctor.js升级到v2.0及以上版本,可以直接使用节点的convert()方法,指定输出格式为asciidoc来重新生成代码。示例如下:
// 确保asciidoctor.js版本>=2.0 const asciidoctor = require("asciidoctor.js")(); const changelogDoc = asciidoctor.loadFile("../user-manual/src/main/asciidoc/Changelog.adoc"); // ... 遍历章节逻辑 ... if (key) { // 从AST重新生成AsciiDoc const sectionAsciidoc = subsubsec.convert({ format: "asciidoc" }); console.log(sectionAsciidoc); return sectionAsciidoc; }
不过注意:你当前使用的是1.5.9版本,这个版本没有内置的AST转AsciiDoc功能,所以升级版本是前提。
为什么getContent()返回HTML?
getContent()方法的默认行为是将章节内容渲染为HTML,这是asciidoctor.js的默认输出格式。如果要改变输出格式,在调用时需要指定backend参数,但旧版本同样不支持asciidoc后端,所以方法1对你当前的版本更实用。
内容的提问来源于stack exchange,提问作者Christoph Stock
相关产品推荐
相关产品推荐

