pandoc自定义过滤器

pandoc自定义过滤器

pandoc是一个强大的文本转换工具,可以实现各种文本格式的互相转换。

在开发过程中常用的文档格式有rst、markdown、pdf、docx等,pandoc支持这些格式互转,但是对于一些特殊格式和排版支持不是太好,需要做一些适配和二次开发。

常见的方式用过滤器方式、模板方式、使用高级参数等来进行调整适配。

但要想达到高度定制,还是需要使用过滤器的方式。

pandoc的工作原理

pandoc使用语法树来进行解析,并且使用json来表示文档的内部抽象语法树,是pandoc文档内容的结构化表述。

pandoc允许用户通过解析和操作json结构来自定义文档内容和格式。

Pandoc 的 JSON 结构(schema)是 Pandoc 文档转换过程中的核心部分,它表示文档的抽象语法树 (AST),允许用户通过解析和操作 JSON 结构来自定义文档内容和格式。JSON schema 的细节可以帮助你理解 Pandoc 如何表示文档中的各类元素(如段落、标题、代码块、表格等)。

以下是 Pandoc JSON schema 的详细介绍:

1. 顶层结构

Pandoc 的 JSON 文件的顶层结构通常包括两个主要部分:

  • meta: 包含文档的元数据,如标题、作者、日期等。
  • blocks: 包含文档的主要内容,以列表的形式表示。每个列表项都是一个块元素,例如段落、标题、列表、表格等。

示例顶层结构:

{"meta": {"title": {"t": "MetaInlines","c": [{"t": "Str", "c": "Sample Document"}]}},"blocks": [{"t": "Para","c": [{"t": "Str", "c": "Hello"},{"t": "Space"},{"t": "Str", "c": "world"}]}]
}
  • meta: 包含文档元数据的对象,通常包括 title, author, date
  • blocks: 是文档主体的内容,这里包含了一个段落 (Para)。

2. 元数据 (meta)

meta 包含文档的元数据信息,可以包括:

  • title: 文档的标题。
  • author: 作者列表。
  • date: 文档的日期。
    元数据可以有多种形式,包括字符串、内联元素或块元素。

示例:

{"title": {"t": "MetaInlines","c": [{"t": "Str", "c": "My Document"}]},"author": {"t": "MetaInlines","c": [{"t": "Str", "c": "Author Name"}]},"date": {"t": "MetaInlines","c": [{"t": "Str", "c": "2024-09-15"}]}
}

3. 块元素 (blocks)

块元素表示文档的结构部分,它可以是段落、标题、列表、代码块等。常见的块元素包括:

  • Para: 段落,内容为内联元素的列表。
  • Header: 标题,包含一个级别(1-6)和内联元素。
  • CodeBlock: 代码块,包含代码和可选的属性。
  • BlockQuote: 引用块。
  • Table: 表格结构。
  • BulletListOrderedList: 列表。

段落 (Para) 示例:

{"t": "Para","c": [{"t": "Str", "c": "This"},{"t": "Space"},{"t": "Str", "c": "is"},{"t": "Space"},{"t": "Str", "c": "a"},{"t": "Space"},{"t": "Str", "c": "paragraph."}]
}

4. 内联元素 (Inlines)

内联元素是嵌入在段落或标题等块元素中的文本或小型元素。常见的内联元素包括:

  • Str: 字符串。
  • Emph: 斜体。
  • Strong: 粗体。
  • Code: 内联代码。
  • Link: 超链接。
  • Image: 图片。

内联代码 (Code) 示例:

{"t": "Code","c": [{"t": "Str", "c": "print('Hello, world!')"}]
}

5. 表格 (Table)

Table 是一个复杂的结构,包含表头、表格主体、对齐方式、列宽等内容。表格的定义较为灵活,允许你指定每列的对齐、列宽、以及包含的内容。

表格的结构示例:

{"t": "Table","c": [[{"t": "AlignLeft"}, {"t": "AlignCenter"}],  # 对齐方式[{"t": "ColWidthDefault"}, {"t": "ColWidthDefault"}],  # 列宽[[{"t": "Plain", "c": [{"t": "Str", "c": "Header 1"}]}],  # 表头[{"t": "Plain", "c": [{"t": "Str", "c": "Header 2"}]}]],[[[{"t": "Plain", "c": [{"t": "Str", "c": "Row 1, Col 1"}]}],  # 表格数据[{"t": "Plain", "c": [{"t": "Str", "c": "Row 1, Col 2"}]}]]]]
}

6. Raw Block/Inline

有时,文档中可能包含特定格式的原始数据(如 HTML 或 LaTeX)。这些内容以 RawBlockRawInline 形式出现,用于保留特定格式的内容。

示例:

{"t": "RawBlock","c": ["html", "<div class='custom-class'>Custom HTML Content</div>"]
}

如何查看pandoc的json格式

以rst文件为例:

pandoc input.rst -f rst -t json

rst转markdown

markdown由于历史原因为了支持更多的格式,衍生出多种markdown方言,pandoc在转换时支持指定gfm、markdown、markdown-strict、commonmark,来确定你所转换的markdown方言。

这里我们想要转换为docsuaurus(Facebook开源的一个文档框架)能识别的格式,因而只能使用commonmark来转换。其转换命令如下:

pandoc rst/input.rst -f rst -t commonmark -o md/output.md

在这里使用一个带有表格、图片、列表、代码块、告警的rst文件,将其转换为md。

图片

rst的代码如下:

.. image:: https://docusaurus.io/zh-CN/img/undraw_typewriter.svg:alt: element

换后的md格式如下:

![element](https://docusaurus.io/zh-CN/img/undraw_typewriter.svg)

可以看到就是markdown的标准语法。

但是rst有一种类型的图片语法,使用figure关键字,pandoc将其转为md后变成了html标签:

rst的代码如下:

.. figure:: https://docusaurus.io/zh-CN/img/docusaurus.svg

转换后的md文件如下:

<figure>
<img src="https://docusaurus.io/zh-CN/img/docusaurus.svg"
alt="https://docusaurus.io/zh-CN/img/docusaurus.svg" />
</figure>

可以看到直接变成了html标签,这个不太符合我们的格式要求,需要对其进行适配。

需要编写figure_filter.py的过滤器,用于对输入内容进行转换,其脚本内容如下:

#!/usr/bin/env python3from pandocfilters import toJSONFilter, Para, RawInlinedef figure_to_markdown(key, value, format, meta):if key == 'Figure':# 获取 Figure 内部的 Plain 节点plain_node = value[2][0]if plain_node['t'] == 'Plain':# 遍历 Plain 中的元素,找到 Imagefor item in plain_node['c']:if item['t'] == 'Image':# 获取 Image 节点中的图片 URLimage_info = item['c']image_url = image_info[2][0]  # 获取图片 URL# 使用 RawInline 插入原始 Markdown 代码,并将其放入 Para 块中return Para([RawInline('markdown', f'![]({image_url})')])if __name__ == "__main__":toJSONFilter(figure_to_markdown)

在转换时使用如下命令进行转换:

pandoc rst/input.rst -t commonmark -o md/output_filter_figure.md --filter=./src/figure_filter.py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54274.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python基础(六)——PyEcharts数据可视化初级版

案例 【前言&#xff1a;为了巩固之前的Python基础知识&#xff08;一&#xff09;到&#xff08;五&#xff09;&#xff0c;并为后续使用Python作为数据处理的好帮手&#xff0c;我们一起来看几个例子】 使用工具&#xff1a;Echarts Echarts 是一个由百度开源的数据可视化…

2024年华为杯广东工业大学程序设计竞赛 B.你是银狼(反悔贪心)

题目链接 B 你是银狼 思路&#xff1a; 发现其实只有房间 1 1 1 有的选&#xff0c;房间 2 , 3 2,3 2,3 都没得选&#xff0c;是一定要选的。房间 2 2 2 回血有益还能房间通过数 1 1 1&#xff0c;因此我们肯定会选。而对于一系列房间 1 1 1&#xff0c;在血量允许的前…

[2025]医院健康陪诊系统(源码+定制+服务)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

【电路笔记】-运算放大器比较器

运算放大器比较器 文章目录 运算放大器比较器1、概述2、表示2.1 同相比较器2.2 反相比较器3、临界点转换4、施密特触发器4.1 同相触发器4.2 反相触发器4.3 应用5、总结1、概述 在前面的大多数运算放大器文章中,电路都有一个到反相输入的反馈环路。 这种设计是最常见的,因为它…

基于SpringBoot+Vue的企业会议室预定管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

Gin渲染

HTML渲染 【示例1】 首先定义一个存放模板文件的 templates文件夹&#xff0c;然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。 posts/index.tmpl {{define "posts/index.tmpl"}} <!DOCTYPE html> <html lang"en">&…

shell指令及笔试题

一&#xff1a;linux基本指令考察 创建文件&#xff0c;直接在本目录的上级目录下创建一个名为dir1的文件夹&#xff0c;并在dir1文件夹下创建一个名为file1的文件 答&#xff1a;本目录的上级目录下创建一个名为dir1的文件:mkdir ../dir1 在dir1文件夹下创建一个名为file1的…

集合是什么

1.是什么 集合&#xff08;Collection&#xff09;是Java语言中一个非常重要的概念&#xff0c;它是一组对象的容器&#xff0c;用于存储、检索和操作对象。在Java中&#xff0c;集合框架定义了一系列接口和实现类&#xff0c;用于处理不同类型的集合。 集合的概念 集合框架提…

TCP/IP - TCP

目录 1. 数据格式2. TCP建立:三次握手第一次握手:Client发出SYN帧(SN=a, AN=0, SYN=1, ACK=0)第二次握手:Server发出SYN+ACK帧(SN=b, AN=a+1, SYN=1, ACK=1)第三次握手:Clietn发出ACK帧(SN=a+1, AN=b+1, SYN=0, ACK=1)为什么是三次握手,而不是两次?建立连接之后,一…

【SQL】百题计划:SQL内置函数“LENGTH“的使用

【SQL】百题计划-20240912 方法一&#xff1a; Select tweet_id from Tweets where LENGTH(content) > 15;– 方法二&#xff1a; Select tweet_id from Tweets where CHAR_LENGTH(content)> 15;

初始c++:入门基础(完结)

打字不易&#xff0c;留个赞再走吧~~~ 目录 一函数重载二引用1 引⽤的概念和定义2引⽤的特性3引⽤的使⽤三inline四nullptr 一函数重载 C⽀持在同⼀作⽤域中出现同名函数&#xff0c;但是要求这些同名函数的形参不同&#xff0c;可以是参数个数不同或者 类型不同。这样C函数调⽤…

HTB-Blue(永恒之蓝漏洞复现)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解Blue靶机 渗透过程 信息搜集 服务器开放了smb服务&#xff0c;漏洞探测显示 具有ms17_010(永恒之蓝漏洞) 利用永恒之蓝 搜索永恒之蓝漏洞 use使用永恒之蓝漏洞 rhost //对方主机 lhost //回连主机 …

一种简单的过某宝验证码的方式(仅做学习使用)

开篇 今天介绍一种简单的过某宝验证码的方式&#xff0c;用的是自动化&#xff0c;这样对不会js逆向的小白非常友好&#xff0c;只需要用到selenium框架就能轻松过某宝验证码&#xff0c;即模拟人的操作对滑块进行滑动。 但是首先还是需要训练验证码和标题 训练前&#xff1a…

Spring Boot,在应用程序启动后执行某些 SQL 语句

在 Spring Boot 中&#xff0c;如果你想在应用程序启动后执行某些 SQL 语句&#xff0c;可以利用 spring.sql.init 属性来配置初始化脚本。这通常用于在应用启动时创建数据库表、索引、视图等&#xff0c;或者填充默认数据。data-locations 和 schema-locations 指定了 SQL 脚本…

心觉:成功学就像一把刀,有什么作用关键在于使用者(二)

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作174/1000天 上一篇文章讲了成功学到底是个啥 是如何起作用的 为什么有些人觉得没有用&#xff1f; 今天我们再展开来剖析一下这…

AI创作新手册:精通Prompt提示词的提问策略

文章目录 &#x1f34a;AI创作核心&#xff1a;提示词 Prompt 的重要性1. 什么是提示词工程&#xff1f;1.1 提示词的作用原理1.2 提示词工程师的薪资与行业前景1.3 提示词工程的适用性 2. 提示词的编写技巧3. 常见的提示词框架3.1 CO-STAR 框架3.2 BORKE 框架 4. 提示词的实际…

openssl 生成多域名 多IP 的数字证书

openssl.cnf 文件内容&#xff1a; [req] default_bits 2048 distinguished_name req_distinguished_name copy_extensions copy req_extensions req_ext x509_extensions v3_req prompt no [req_distinguished_name] countryName CN stateOrProvinceName GuangDong l…

Electron 安装包 asar 解压定位问题实战

背景 在开发 Electron 过程中&#xff0c;我们想知道 Electron 打包的最终形态是什么样的&#xff0c;以便我们能更好的理解 Electron 打包的过程&#xff0c;以及逆向来快速追踪一些问题&#xff0c;例如下面这个报错&#xff0c;以前这类报错都是靠猜&#xff0c;现在则可以…

使用 VSCode 在 Python 中创建项目环境

了解如何管理 Python 项目的不同环境&#xff0c;欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 介绍 创建数据科学项目非常简单。如今&#xff0c;有了众多资源&#xff0c;您只需选择开发工具并启动项目即可。 除了多个人工智能机…

git pull的merge和rebase模式

git pull 命令用于将远程仓库的更改拉取到本地仓库&#xff0c;并合并到当前分支中。git pull 默认使用合并&#xff08;merge&#xff09;模式&#xff0c;但也可以选择使用变基&#xff08;rebase&#xff09;模式。 Merge 模式&#xff08;默认模式&#xff09; git pull …