跳转到主要内容

Ruamel Yaml Doc预处理器(发音:/rɑɪt/,类似于动词“写”)

项目描述

ryd

image image image image

ryd(/rɑɪt/,发音类似于动词“写”)是一种基于文本的文档预处理器,它基于YAML文件/流的文档多文档功能。

ryd中使用多个文档可以在文档文本和这些文本中引用的任何程序之间进行清晰的分离。因此,可以运行(即编译)文档的程序部分,例如,检查它们是否在语法上是正确的。它还可以捕获这些程序的实际输出并将其包含在文档中。还可能识别不同的文档,因此可以运行不同的格式化程序然后重新组合文档。

这允许在文档源文本(如reStructuredText、LaTeX、Markdown等)中更容易地维护(正确)的程序源。

ryd文件的文档中,第一个文档在根级别上有一个映射。这个映射是该文件中其余文档流的ryd配置元数据。元数据用于定义所使用的ryd文档版本、基本的文本样式(目前为RestructuredText的rst,StackOverflow-markdown的so),是否需要进行任何后处理(PDF、HTML),以及其他配置信息。这个第一个文档通常没有任何指令。由于该文档是YAML 1.2的,这是隐含的,因此不需要%YAML 1.2指令,且没有指令和前导文档,你顶部不会有指令结束标记行(---)。

第一个文档之后的文档通常是有可选标签的块风格字面量标量。标签影响所选输出文本样式中对标量字符串的处理。

示例

version: 0.2
text: rst
fix_inline_single_backquotes: true
--- |
Example Python program
++++++++++++++++++++++

This is an example of a python program:
--- !python |
n = 7
print(n**2 - n)
--- !stdout |
The answer is:

这将生成以下test.rst(使用:ryd convert test.ryd

Example Python program
++++++++++++++++++++++

This is an example of a Python program:

.. code:: python

  n = 7
  print(n**2 - n)

The answer is:

.. code::

  42

后处理

可以使用rst2pdf将其转换为PDF,或使用rst2html转换为HTML,并使用webpage2html嵌入图像。这些程序的调用可以在元数据中指定(例如post: pdf)。

(图像嵌入)HTML输出的缩进是实际插入的缩进行的空白。因此,您可以从HTML中复制和粘贴程序代码(或YAML)而不会出现问题,这是使用rst2pdf生成的PDF文件无法实现的。

ryd独立生成其文本输出,但用于后处理的实际程序必须单独安装并可在您的PATH中找到。

(目前对Markdown没有后处理,因为pandoc在Arch上无法工作(2022年3月))

配置

您可以创建一个文件~/.config/ryd/ryd.yaml,其中包含命令行选项的默认值。在转换为HTML时始终嵌入图像,并始终运行(全局)详细选项

全局

: verbose: true

convert

: embed: true

命令行选项

ryd的命令行由多个组件组成

ryd [--global-option] command [--options] [arguments]

尽管没有指示,但大多数全局选项也可以在命令之后出现。

commands

convert             generate output as per first YAML document
roundtrip           roundtrip .ryd file, updating sections
from-rst (fromrst)  convert .rst to .ryd

您最常使用的是convert,它接受一个或多个文件名作为参数,并根据ryd配置数据生成输出。一些选项允许您覆盖那里的设置(例如--pdf-no-pdf

from-rst命令将.rst文件转换为.ryd,进行一些部分下划线检查并添加ryd配置数据文档。

roundtrip命令通过在.ryd文件的!python(使用oitnb)和!zig部分运行原地代码格式化来更新部分。(目前没有配置选项使用blueblack,但您可以将ryd/_tag/python.tag复制到您的.config/ryd/tag目录,并对它们进行一些调整以使用这些,请参阅制作自己的标记部分)

运行ryd command --help可能会指示一些额外的选项尚未进入文档,或者这些选项尚未完全实现。

文档和文档标签

每个YAML文档必须通过至少一个指令结束标记---与其他文档流中的文档分开。除了第一个文档之外,大多数文档包含一个单行、非缩进的标量。因此,指令结束标记之后跟着的是管道符号(|),它是YAML表示多行字面量标量的符号。

该标量可以像YAML中通常的方式“类型化”,即在|之前插入一个标签。例如,一个类型为Python程序的文档有一个标签!python,因此它以以下方式开始

--- !python |

文档标签具体做什么,取决于标签本身,但可能还取决于所选的输出文件格式、之前处理过的带标签文档、之前处理过的其他.ryd文件和环境。

除了基本标签(如!python)之外,标签还可以有子功能,如!python-pre。如果指定了未知的子功能,您将收到运行时错误。

以下是对所有标签的简要描述,不依赖于所选的输出格式

!changelog
输入是一个映射,键是(版本,日期)元组,或者是单词NEXT

!code
将程序包含在文本中。不要将其标记为可执行,不影响!stdout

!comment
整个文档将被丢弃,即不包含在输出中。

!inc
将列出文件的 内容(缩进)包含到输出中,不进行其他处理。如果需要,在前面加上::

!inc-raw
将列出文件的 内容(缩进)包含到输出中,不进行其他处理。如果需要,在前面加上::

!lastcompile
将上一次编译的输出作为代码包含。

!nim
将Nim程序包含在文本中。加前缀并标记为可执行。

!nim-pre
将Nim程序包含在文本中。加前缀并标记为可执行。

!python
将Python程序包含在文本中。加前缀并标记为可执行。

!python-hidden
将Python程序包含在文本中。加前缀并标记为可执行。

!python-hiddenstdoutraw
将Python程序包含在文本中。加前缀并标记为可执行。

!python-pre
将Python程序包含在文本中。加前缀并标记为可执行。

!stdout
将上一次可执行文档(例如!python)的输出作为代码包含。

!stdout-raw
将上一次可执行文档(例如!python)的输出作为代码包含。

!table
创建一个表,目前没有表头

!toc
插入索引

!yamlout
将上一次可执行文档(例如!python)的输出作为代码包含,并标记为YAML文档。

!zig
将Zig程序包含在文本中。加前缀并执行设置!stdout。

!zig-pre
将Zig程序包含在文本中。加前缀并执行设置!stdout。

!zsh
在zsh中运行每一行,交替着输出

MD

输出到.md期望非代码YAML文档是有效的Markdown。

由于行首的---(和...)具有特殊含义,后面跟换行符或空格,因此不应使用这些。可以使用更长的序列(例如,对于分隔线使用----),或者将整个文档缩进。

  --- |
    line followed by divider
    ---
    another line

mkdocs

如果您有一个文件_doc/README.ryd,您可以使用ryd serve将其转换为mkdocs并服务。必要的mkdocs配置文件的 内容将从README.ryd文件的元数据中的mkdocs条目写入(因此您不需要在包的根目录中放入更多垃圾)

 version: 0.2
 text: md
 pdf: false
 mkdocs:
   # if site_name key not provided set to current directory name
   site_name: your_project_name
   docs_dir: _doc
   site_author: Anthon van der Neut

   theme:
     name: readthedocs

   exclude_docs: |
     *.ryd
     *.rst

   markdown_extensions:
   - toc:
       permalink: true

RST

输出到.rst期望非代码YAML文档是有效的reStructuredText。任何未标记的文档,即那些以

--- |

开始的文档,假设是文本输入,格式由ryd配置数据指定。

章节下划线

由于行首的---(和...)具有特殊含义,后面跟换行符或空格,因此.ryd文件中用于.rst的章节下/上划线字符不应使用-.序列,如果任何这些章节名称由三个字母组成(例如,名为API或RST的章节)。建议使用以下方案

Sections, subsections, etc. in .ryd files
 # with over-line, for parts
 * with over-line, for chapters
 =, for sections
 +, for subsections
 ^, for sub-subsections
 ", for paragraphs

单引号

fix_inline_single_backquotes: true告诉ryd指示需要修复的包含单引号的行(通过将它们替换为双引号)

README.ryd
47: this will generate (`ryd convert test.ryd`) the following
                      --^
                                           --^

(如果您习惯于其他内联代码标记编辑,例如Stack Overflow上使用的单引号,您将开始欣赏这一点。)

Python

Python代码是通过

--- !python |

将文档插入到.rst之前,并带有.. code:: python,并且每一行带有两个空格的缩进。

如果您的程序依赖于特定软件包,那么这些软件包需要可在启动ryd的环境中进行(例如,可以是专门设置的virtualenv

可以通过在Python文档前面加上例如

--- !python-pre |
from __future__ import print_function
import sys
import ruamel.yaml
from ruamel.std.pathlib import Path, pushd, popd, PathLibConversionHelper
pl = PathLibConversionHelper()

这样的块将添加到所有随后的--- !python |文档之前(直到由另一个--- !python-pre |块替代)

捕获的输出

上次运行的程序输出(--- !python |)已存储,并可以通过添加!stdout标签(即--- !stdout |)将其附加到reStructuredText文档中。

未运行的代码

标记为!code的文档将表示为标记为!python的文档,但代码不会运行(因此用于!stdout的输出不会更改)。

Zig

Zig代码通过以下方式表示:

--- !zig |

文档的插入方式与Python相同,可以有!zig-pre文档,输出通过--- !stdout |捕获并显示)

// const std = @import("std");   is defined in zig-pre

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("Hello, {s}!\n", .{"world"});
}

输出如下

Hello, world!

编译使用选项build-exe

编译器输出 ^^^^^^^^^^^^^^^

如果您对编译器的文本输出感兴趣,可以使用--- !lastcompile |

Nim

Nim代码通过以下方式表示:

--- !nim |

文档的插入方式与Python相同,可以有!nim-pre文档,输出通过--- !stdout |捕获并显示)

let a = 123
let x = 0b0010_1010
echo(fmt"The answer to the question: {x}")

输出如下

The answer to the question: 42

编译使用选项--verbosity:0 --hint[Processing]:off .

编译器输出

如果您对编译器的文本输出感兴趣,可以使用--- !lastcompile |

/tmp/ryd-of-anthon/ryd-1169/tmp_02.nim(4, 5) Hint: 'a' is declared but not used [XDeclaredButNotUsed]

注释

块样式字面量标量不允许YAML注释。要在文本中插入注释,可以使用输出的格式,例如,当生成.rst时使用

..
   this will show up in the resulting .rst file, but will
   not render

或者您也可以创建一个注释YAML文档(--- !comment |),其中文本将不会以任何方式表示在输出文件格式中。

如果您已经有一个标记的文档,例如--- !python |文档,您可以通过插入comment-将其转换为注释。

--- !comment-python |

这是通过在调用!comment上的未知子函数时报告错误来实现的。

任务列表

如果您在元数据中设置tasklist: true,则以下任务列表模式之一开头的行将转换为它们的unicode对应项

[ ] not done yet
[v] done
[x] no longer going to do

结果如下

☐ 尚未完成

☑ 完成

☒ 不再进行

(如果能以用户指定的项目符号项创建一个真正的列表那会很好)

创建自己的标签

在尝试从已知文件加载!yourtag标签之前,ryd会尝试从~/.config/ryd/tag/加载它们。此机制可以用来实现您对现有标签的改进或扩展标签以包含您自己的。

假设您想在ryd文档中解释mypy的使用,包括对某些源代码执行的mypy输出。首先创建一个名为~/.config/ryd/tag/mypy.tag的文件,其内容如下

# coding: 'utf-8'

from __future__ import annotations

import os
import subprocess
from typing import Any, TYPE_CHECKING
from ryd._tag._handler import ProgramHandler

if TYPE_CHECKING:
    from ryd._convertor._base import ConvertorBase
else:
    ConvertorBase = Any


class Mypy(ProgramHandler):   # class name is capitalization of the stem of the filename
    def __init__(self, convertor: ConvertorBase) -> None:
        super().__init__(convertor)
        self._pre = ''

    def pre(self, d: Any) -> None:  # like !python-pre you can have !mypy-pre
        self._pre = str(d)

    def __call__(self, d: Any) -> None:
        """
        Include Python program in text. Prefix, save and run mypy, setting !stdout.
        """
        s = str(d)
        # depending on the util, you may not need to do a chdir to the tempdir
        old_dir = os.getcwd()
        self.c.temp_dir.chdir()
        path = self.c.temp_file_path('.py')
        path.write_text(self._pre + s)
        self.c.last_output = subprocess.run([
            'mypy',
            '--strict', '--follow-imports', 'silent', '--implicit-reexport',
            str(path),
        ], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, encoding='utf-8').stdout
        os.chdir(old_dir)
        self.c.add_code(s, 'python')  # format the code as python

然后您将其包含在您的ryd文档中

--- !mypy |
def main(arg1, arg2):
    return arg1

--- !stdout |
which gives:

--- |

from the mypy output you can see ....

您的.rst将包含Python源代码和mypy输出

.. code:: python

  def main(arg1, arg2):
      return arg1

which gives:

.. code::

  tmp_03.py:2: error: Function is missing a type annotation
  Found 1 error in 1 file (checked 1 source file)

from the mypy output you can see ....

历史

ryd是从一个内部解决方案发展而来的,该解决方案通过运行单独文件中指定的Python程序来就地更新reStructuredText文件的某些部分。还允许包含(错误)输出。

可以在这里看到此example.rst文件的旧版本,它是ruamel.yaml包的一部分。

Basic round trip of parsing YAML to Python objects, modifying
and generating YAML::

  import sys
  from ruamel.yaml import YAML

  inp = """\
  # example
  name:
    # details
    family: Smith   # very common
    given: Alice    # one of the siblings
  """

  yaml = YAML()
  code = yaml.load(inp)
  code['name']['given'] = 'Bob'

  yaml.dump(code, sys.stdout)

.. example code small.py

Resulting in ::

  # example
  name:
    # details
    family: Smith   # very common
    given: Bob      # one of the siblings


.. example output small.py

程序在.. example code行之前插入,其输出在.. example output之前,替换了所有::之后的文本。

small.py引用了一个单独的文件来存储这部分代码。这导致多个源文件与单个.rst文件相关联。没有机制可以拥有部分程序,这些程序可以通过执行进行测试,这也排除了从这些程序获取输出的可能性。

尽管代码可以就地编辑并用于获取输出,但这会强制人们使用ReST的::之后的额外缩进。

一旦这个系统开始审查,选择了具有结构化YAML头部的解决方案,如用于各种文件格式,结合多个包含(标记的)顶级、非缩进的块样式字面量标量文档。

2022年初,0.1格式的更新实现了将标签和转换器放入单独的文件中,从而使得它们更容易升级和扩展。

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

ryd-0.9.2.tar.gz (52.9 kB 查看散列)

上传时间 源代码

构建分发

ryd-0.9.2-py3-none-any.whl (51.0 kB 查看散列)

上传时间 Python 3

支持