Как получить подписи с уценкой в ​​pandocfilters? - PullRequest
1 голос
/ 28 января 2020

Я попробовал фильтр PlantUML , чтобы сгенерировать цифры LaTeX из кода PlantUML в источнике уценки. Он работает хорошо (я изменил его для создания PDF для LaTeX, поскольку он сохраняет текстовые элементы на диаграммах PlantUML).

Проблема этого фильтра (и всех фильтров, использующих API pandocfilters) заключается в том, что заголовки не поддерживают уценку. То есть пропуск caption="Here is a diagram that is *not* what you'd expect." приведет к тому, что в LaTeX будет фигура * not *, а не not (курсивом).

Мой обходной путь - добавить два ключа в фильтр : hide-image=true и plantuml-filename=foo.pdf (логика c не должна ничего возвращать в AST для диаграммы и создавать выходной файл foo.pdf). Затем я могу получить форматирование заголовка уценки, используя традиционную фигуру:

```{.plantuml hide-image=true plantuml-filename=foo.pdf}
@startuml
A -> B : hello
@enduml
```

![Here is a diagram that is *not* what you'd expect](foo.pdf)

Это хорошо работает, но определение имени файла - дополнительная работа.

get_caption в pandocfilters.py выглядит следующим образом:

def get_caption(kv):
    """get caption from the keyvalues (options)
    Example:
      if key == 'CodeBlock':
        [[ident, classes, keyvals], code] = value
        caption, typef, keyvals = get_caption(keyvals)
        ...
        return Para([Image([ident, [], keyvals], caption, [filename, typef])])
    """
    caption = []
    typef = ""
    value, res = get_value(kv, u"caption")
    if value is not None:
        caption = [Str(value)]
        typef = "fig:"

    return caption, typef, res

Есть ли (простой) способ изменить это так, чтобы get_caption мог соблюдать уценку внутри?

Inline (я подумал, что это может быть способ указать, что заголовок содержит уценку) не является конструктором, определенным в pandocfilters.py, возможно потому, что когда фильтр вызывается при обработке, это не считается вложенным.

Моя (взломанная) версия фильтра PlantUML находится на GitHub:

#!/usr/bin/env python

"""
Pandoc filter to process code blocks with class "plantuml" into
plant-generated images.

Needs `plantuml.jar` from http://plantuml.com/.
"""

import os
import shutil
import sys
from subprocess import call

from pandocfilters import toJSONFilter, Para, Image, get_filename4code, get_caption, get_extension


def plantuml(key, value, format, _):
    if key == 'CodeBlock':
        [[ident, classes, keyvals], code] = value

        if "plantuml" in classes:
            caption, typef, keyvals = get_caption(keyvals)

            filename = get_filename4code("plantuml", code)
            filetype = get_extension(format, "png", html="svg", latex="pdf")

            src = filename + '.puml'
            plantuml_output = filename + '.' + filetype

            dest_spec = ""
            # Key to specify final destination the file
            for ind, keyval in enumerate(keyvals):
                if keyval[0] == 'plantuml-filename':
                    dest_spec = keyval[1]
                    keyvals.pop(ind)
                    break

            # Generate image only once
            if not os.path.isfile(plantuml_output):
                txt = code.encode(sys.getfilesystemencoding())
                if not txt.startswith("@start"):
                    txt = "@startuml\n" + txt + "\n@enduml\n"
                with open(src, "w") as f:
                    f.write(txt)
                # Must not let messages go to stdout, as it will corrupt JSON in filter
                with open('plantUMLErrors.log', "w") as log_file:
                    call(["java", "-jar", "filters/plantuml/plantuml.jar", "-t"+filetype, src], stdout=log_file)
                sys.stderr.write('Created image ' + plantuml_output + '\n')
                if not dest_spec == "": 
                    sys.stderr.write('Copying image from ' + plantuml_output + ' to ' + dest_spec + '\n')
                    shutil.copy2(plantuml_output, dest_spec)
                    plantuml_output = dest_spec


            for ind, keyval in enumerate(keyvals):
                if keyval[0] == 'hide-image':
                    if keyval[1] == 'true':
                        sys.stderr.write('Not showing image ' + plantuml_output + '\n')
                        return [] # surpress image in JSON

            return Para([Image([ident, [], keyvals], caption, [plantuml_output, typef])])

if __name__ == "__main__":
    toJSONFilter(plantuml)
...