Проблема создания файла уценки из python - PullRequest
0 голосов
/ 18 февраля 2019

У меня проблема при использовании Python для генерации PDF-файлов из уценки.Моя цель здесь - преобразовать мою документацию в pdf.Для этого у меня уже есть команда оболочки, которая выглядит следующим образом:

markdown <markdown filename>.md | htmldoc --cont --headfootsize 8.0 --linkcolor blue --linkstyle plain --charset utf-8 --format pdf14 - > <pdf filename>.pdf

Чтобы использовать ее, вам нужно установить markdown и htmldoc:

sudo apt-get update
sudo apt-get install markdown
sudo apt-get install htmldoc

Так что теперь я хочу автоматизироватьпоколение.Я хочу использовать python с его основной библиотекой subprocess в 3.6, поэтому вот код:

import subprocess
import os
import sys
import getopt
import shutil


def list_markdown_file(path):
    # this function list all markdown file
    # param path = path to the target directory

    list_of_file = []
    for file in os.listdir(path):
        if file.endswith(".md") and not file == 'README.md':
            list_of_file.append(os.path.splitext(file)[0])
    return list_of_file


def generate_pdf(path, list_file):
    destination_dir = "pdf"
    if os.path.isdir(os.path.join(path, destination_dir)):
        shutil.rmtree(os.path.join(path, destination_dir))
    os.mkdir(os.path.join(path, destination_dir))

    for filename in list_file:
        subprocess.run(["markdown", filename+".md", "|", "htmldoc", "--cont",
                        "--headfootsize", "8.0", "--linkcolor", "blue", "--linkstyle",
                        "plain", "--charset", "utf-8", "--format", "pdf14", "-", ">",
                        os.path.join(path, destination_dir, filename+".pdf")], encoding='utf-8', stdout=subprocess.PIPE)


def main(argv):
    try:
        opts, args = getopt.getopt(argv, "hp:", ["path"])
    except getopt.GetoptError:
        print('python generate_pdf.py -p <path_to_directory>')
        sys.exit(2)
    path_to_file = ''
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            print('python generate_pdf.py -p <path_to_directory>')
            sys.exit()
        elif opt in ("-p", "--path"):
            path_to_file = arg
    if not opts:
        print('python generate_pdf.py -h to see how its works')
        exit(2)
    list_of_file = list_markdown_file(path=path_to_file)
    generate_pdf(path=path_to_file, list_file=list_of_file)


if __name__ == '__main__':
    main(sys.argv[1:])

Проблема находится в этой части:

for filename in list_file:
    subprocess.run(["markdown", filename+".md", "|", "htmldoc", "--cont",
                    "--headfootsize", "8.0", "--linkcolor", "blue", "--linkstyle",
                    "plain", "--charset", "utf-8", "--format", "pdf14", "-", ">",
                    os.path.join(path, destination_dir, filename+".pdf")], encoding='utf-8', stdout=subprocess.PIPE)

Когда я это делаювыполняется только часть с markdown filename.md.Это почему?Что я могу сделать, чтобы это исправить?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

subprocess без shell=True запускает один подпроцесс.Если вы хотите запустить полный конвейер, вам нужно использовать shell=True или запускать каждый процесс отдельно.

Тривиально, но непривлекательно с shell=True:

for filename in list_file:
    # Switch run([list, of, things]) to (run("string of things", shell=True)
    subprocess.run("""markdown '{0}.md' |
        htmldoc --cont --headfootsize 8.0 --linkcolor blue --linkstyle plain \\
            --charset utf-8 --format pdf14 - >'{1}'""".format(
            filename, os.path.join(path, destination_dir, filename+".pdf"),
        shell=True)

Возможно, немного более элегантно

for filename in list_file:
    with open(os.path.join(path, destination_dir, filename+".pdf")) as dest:
        subprocess.run("""markdown '{0}.md' |
            htmldoc --cont --headfootsize 8.0 --linkcolor blue --linkstyle plain \\
                --charset utf-8 --format pdf14 -""".format(filename),
            shell=True, stdout=dest, universal_newlines=True, check=True)

Вы также можете избавиться от shell=True и запустить два отдельных процесса;см. Замена конвейера оболочки в документации subprocess.

Просто чтобы сделать это явным, subprocess.run(['foo', 'bar', '|' 'baz']) запускает программу foo с аргументами bar, | иbaz;не два процесса, где второй равен baz, а стандартный вход второго подключен к стандартному выходу первого, что и делает оболочка при запуске конвейера.

0 голосов
/ 18 февраля 2019

Вы можете конвертировать файл Markdwen в файл PDF с помощью модуля Python с именем Markdown2PDF, установить его в Python 3 с помощью sudo pip3 install Markdown2PDF.Откройте Терминал и напишите md2pdf <file_name> как md2pdf test.md, чтобы преобразовать в pdf.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...