Рубрики
Без рубрики

Крепеж Python Markdown Code Blocks … с Python!

Я разбил быстрый скрипт, который я писал, чтобы исправить вывод Markdown из приложения для записи Ulysses. Помечено с Python, сценарием, CLI, Bash.

Быстрое примечание: все блоки кода RAW MACKDOND в фрагментах кода здесь отображаются с одиночными кавычками, а не фактическими backticks, поскольку все вложенные Backticks воспроизводят Havoc с помощью Render render render. Если вы копируйте вставку, вам придется изменить обратно к BackTicks в коде Python.

Я пытаюсь Улисс Для письма, и до сих пор мне очень нравится. Но вчера я пошел на экспорт один из моих постов, чтобы узнать, чтобы подготовиться к публикации в моем блоге, и я нашел небольшой иккуп. Ulysses форматирует все блоки кода с вкладками вместо пробелов. Теперь, когда я собираюсь войти в что Все, но я по крайней мере скажу, что Pep8 говорит нам, что стандарт для Python – 4 пробела. Какое уважение к самоуважанию технического блоггера я буду, если я разместил образцы кода с- шуддер -Табес в моем коде Python?

Так я спросил их!

И они ответили действительно быстро и вежливо сказали мне «не в это время». Который в порядке.

Я сразу начал исследовать, чтобы выяснить, как я собирался решить проблему самому. Могу ли я посмотреть на настройку форматов Markdown? Настройка процесса экспорта? Но прежде чем я смогу начать Spraling на эту кролику, она ударила меня: это просто текст!

Я программист! У меня есть сила вселенной у моих пальцев! (На моей машине, по крайней мере.) Поэтому я должен работать над сценарием для платформы, которая была Разработан Работать с, изменить и настроить потоки текста: командная строка.

Bash One-lister

Моя первая мысль была то, что это настоящая простая замена. Я могу сделать это в одной команде!

$ sed $'s/\t/    /g' example.md
Hello this is text

'''python
def thing():
    print("Spaces!")
'''

There should be four spaces there.

И честно, это, вероятно, достаточно хорошо. Но я был на рулоне, и я хотел немного более мелкозернистый контроль.

Давайте сделаем это в Python

Я покажу вам все это для тех, кто только здесь для копирования/вставки, а затем я пойду через важные биты и как они работают. По сути, мы зацикливаемся через каждую строку входного потока, и если мы находимся в блоке кода Python и есть вкладка, мы заменяем вкладки пробелами. Я тяну в argparse. и fileInput Из стандартной библиотеки, чтобы поставить немного польский на пользовательский опыт. Вот что я придумал:

#!/usr/bin/env python3

import argparse
import fileinput

parser = argparse.ArgumentParser(description="Convert tabs in markdown files to spaces.")
parser.add_argument("-a", "--all", action="store_true", help="Convert all tabs to spaces")
parser.add_argument("-n", "--number", type=int, default=4, help="Number of spaces to use.")
parser.add_argument('files', metavar='FILE', nargs='*', help="files to read, if empty, stdin is used")

args = parser.parse_args()
if args.all:
    start_tag = "'''"
else:
    start_tag = "'''python"

in_code_block = False
for line in fileinput.input(files=args.files):
    if line.startswith(start_tag) and not in_code_block:
        in_code_block = True
    elif line.startswith("'''") and in_code_block:
        in_code_block = False
    elif in_code_block:
        line = line.expandtabs(args.number)

    print(line, end="")

Мясо бизнес-логики здесь:

in_code_block = False
for line in fileinput.input(files=args.files):
    if line.startswith(start_tag) and not in_code_block:
        in_code_block = True
    elif line.startswith("'''") and in_code_block:
        in_code_block = False
    elif in_code_block:
        line = line.expandtabs(args.number)

    print(line, end="")

Структура через каждую строку, отслеживать, если мы находимся в блоке кода (больше на специфике этого через минуту) или нет. Если мы находимся в блоке кода, разверните вкладки! Наконец, выведите новую версию линии.

Но что такое все, что другие вещи? Даже в главном коде, есть ссылка на fileInput Отказ Какого черта?

Использование fileInput.

fileInput Это аккуратный (и откровенно недооцененный) модуль в стандартной библиотеке Python, которая позволяет сценариям загружать вход от одного или многих аргументов файла и даже STDIN Super Ergonomine. Наиболее распространенным использованием регистрируется в Документы для этого И это почти комично коротко:

import fileinput

for line in fileinput.input():
    process(line)

С помощью этих строк кода вы можете вызвать свой скрипт с таким количеством файлов, как вы хотите, и Python будет строгать их содержимое вместе в один поток текста. Например, если у вас есть скрипт, который печатает капитализированную версию всего текста, который он получает под названием Capitalize.py Вы могли бы запустить его так:

$ python3 capitalize.py README.md hello.txt banana.rb
# THIS IS THE TITLE OF MY README

CHECK OUT THE README CONTENTS.
SO MANY CONTENTS.
NOW HELLO.TXT IS HERE
YOOOOOOOO
DEF BANANA
    PUTS 'A MAN, A PLAN, CANAL BANANAMA'
END

Но Райан, в вашем скрипте выглядит разным! Вы не используете это так же! Верно. Я объединяю его с другим модулем Power CLI:

Разборные аргументы с аргапарсом

argparse Стандартный путь библиотеки обрабатывающих аргументы командной строки, флаги, параметры и предоставление небольшого пользовательского интерфейса. Свой особенный синтаксис – это тот, который я всегда должен посмотреть, но это легкий, работает хорошо, и делает то, что я хочу. Вот этот соответствующий код. Вы увидите, как он начинает завязать в fileInput раздел выше.

parser = argparse.ArgumentParser(description="Convert tabs in markdown files to spaces.")
parser.add_argument("-a", "--all", action="store_true", help="Convert all tabs to spaces")
parser.add_argument("-n", "--number", type=int, default=4, help="Number of spaces to use.")
parser.add_argument('files', metavar='FILE', nargs='*', help="files to read, if empty, stdin is used")

args = parser.parse_args()
if args.all:
    start_tag = "'''"
else:
    start_tag = "'''python"

Мы идем на три этапа:

  1. Сначала мы создаем ArgumentParser Отказ Это будет управлять всем нашим расставанием для нас.
  2. Затем мы добавляем аргументы и укажите их поведение. В этом случае я добавил - Все Флаг, чтобы сделать это, чтобы мы могли искоренить все вкладки и восстановить заказ на все наши кодовые блоки, а также - Нет. Флаг, чтобы сказать ему, сколько пробелов сделать каждую вкладку. Это может быть полезно, если у меня есть примеры Ruby или JS, где я предпочитаю 2 пробела. Наконец, я добавляю * args -Провочный позиционный аргумент для всех файлов имена пользователей хочет предоставить.
  3. Наконец, теперь, когда все указано, мы разбираем и обрабатываем args. В зависимости от типа и действий мы указываем для каждого ввода, мы можем ожидать различных поведений.

Последний маленький трюк – это то, как мы привязываем argparse и fileInput вместе с этой маленькой линией:

for line in fileinput.input(files=args.files):

fileInput.input Получает дополнительный список имена файлов, а не пытаться получить их от прошедших аргументов скрипта. Потому что argparse Созывывают все аргументы командной строки, нам нужно сказать ей, чтобы пройти эти файлы через так fileInput могу сделать свою вещь. И все это работает как шарм!

Вкладки для людей, которые смешают их кукурузу и картофель вместе

Нет, у меня нет сильных мнения о тривиальных вещах, почему вы спрашиваете? В любом случае до тех пор, пока этот запрос на функцию Ulysss проходит через свою очередь, у меня есть мой маленький скрипт, и это делает меня счастливым! Насколько хорошо это работает, вы спрашиваете? Ну, вы видите вкладки или пробелы в примерах кода в этом посте?

Слияние Я знаю, что у вас командная строка, одноклассники скрываются, просто умирают, чтобы бросить awk или Sed String на меня, которые сделают именно то, что я хочу без меня, чтобы написать одну линию чрезвычайно читаемого, ремонтопригодных, нерегерных Python. 😉 Я хочу увидеть это! Давайте летать!

Оригинал: “https://dev.to/rpalo/fixing-python-markdown-code-blocks-with-python-2mng”