如何使用pypandoc将JSON嵌套列表转换为Markdown格式?
RuntimeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_7128/3771718373.py in
----> 1 result = pypandoc.convert_text(json.dumps(items), format="json", to="md")
~\anaconda3\lib\site-packages\pypandoc_init_.py in convert_text(source, to, format, extra_args, encoding, outputfile, filters, verify_format, sandbox, cworkdir)
93 return _convert_input(source, format, 'string', to, extra_args=extra_args,
94 outputfile=outputfile, filters=filters,
95 verify_format=verify_format, sandbox=sandbox,
~\anaconda3\lib\site-packages\pypandoc_init_.py in _convert_input(source, format, input_type, to, extra_args, outputfile, filters, verify_format, sandbox, cworkdir)
418 raise RuntimeError(
419 'Pandoc died with exitcode "%s" during conversion: %s' % (p.returncode, stderr)
420 )
RuntimeError: Pandoc died with exitcode "64" during conversion: JSON parse error: Error in $: mempty
我想知道:是否可以使用`pypandoc`将JSON转换为MD?第一个示例中返回的JSON是否是`pandoc`的内部表示,可后续转换为MD?我需要做些什么才能实现该转换? --- ## 解决方案 ### 问题核心 你遇到的问题本质是:`pypandoc`支持的`json`输入格式是**Pandoc专属的AST(抽象语法树)结构**,不是普通的JSON数据。直接传入嵌套列表的JSON字符串,Pandoc无法解析,因此报错。 而第一次调用`convert_text(json.dumps(items), to="json", format="md")`,实际是把JSON字符串当作普通Markdown文本解析,再转成Pandoc的AST JSON,这和你想要的“JSON转Markdown”完全不是一回事。 ### 推荐实现方式 对于这种简单的嵌套列表转换,直接写递归函数生成Markdown是最高效的方案,无需依赖`pypandoc`。针对你提供的特定数据结构(父项与子列表相邻),示例代码如下: ```python def convert_to_markdown(items): md_lines = [] index = 0 while index < len(items): current = items[index] if isinstance(current, str): # 添加主列表项 md_lines.append(f"- {current}") # 检查下一个元素是否是子列表 if index + 1 < len(items) and isinstance(items[index + 1], list): # 添加子列表项 for sub_item in items[index + 1]: md_lines.append(f" - {sub_item}") index += 2 # 跳过子列表 else: index += 1 else: # 处理单独的列表(如果存在) for sub_item in current: md_lines.append(f"- {sub_item}") index += 1 return "\n".join(md_lines) # 测试 items = [ "Item A", "Item B", "Item C", ["Sub Item C.1", "Sub Item C.2", "Sub Item C.3"], "Item D", ["Sub Item D.1", "Sub Item D.2"], "Item E" ] print(convert_to_markdown(items))
运行后会输出你预期的结果:
- Item A - Item B - Item C - Sub Item C.1 - Sub Item C.2 - Sub Item C.3 - Item D - Sub Item D.1 - Sub Item D.2 - Item E
若坚持使用pypandoc
如果一定要用pypandoc,需要先将你的JSON列表转换为Pandoc的AST JSON格式,再转换为Markdown。Pandoc的AST要求明确的块元素定义,示例代码如下:
import json import pypandoc def build_pandoc_ast(items): ast_blocks = [] index = 0 while index < len(items): if isinstance(items[index], str): # 创建主列表项内容 main_content = [{"t": "Str", "c": items[index]}] if index + 1 < len(items) and isinstance(items[index + 1], list): # 创建子列表 sub_list = { "t": "BulletList", "c": [{"t": "Plain", "c": [{"t": "Str", "c": sub}]} for sub in items[index + 1]] } # 将主项和子列表组合成一个块 ast_blocks.append({ "t": "Plain", "c": main_content + [{"t": "SoftBreak"}] + [sub_list] }) index += 2 else: ast_blocks.append({"t": "Plain", "c": main_content}) index += 1 else: # 处理单独的列表 ast_blocks.append({ "t": "BulletList", "c": [{"t": "Plain", "c": [{"t": "Str", "c": sub}]} for sub in items[index]] }) index += 1 # 构建完整的AST结构 full_ast = { "pandoc-api-version": [1, 22, 2, 1], "meta": {}, "blocks": [{"t": "BulletList", "c": ast_blocks}] } return json.dumps(full_ast) # 生成AST并转换 ast_json = build_pandoc_ast(items) result = pypandoc.convert_text(ast_json, format="json", to="md") print(result)
不过这种方式复杂度高,维护成本也高,远不如直接生成Markdown简洁。
内容的提问来源于stack exchange,提问作者jlandercy

