Use saída processada de stdin como uma string de substituição em Sed

0

O comando a seguir me fornece a saída que desejo:

$ sed '/^<template.*>/,/<\/template>/!d;//d' src/components/**/*.vue | html2jade

em que processa cada modelo contendo html em seu pug equivalente.

Seria possível substituir o html originalmente encontrado em todos esses arquivos, com essa saída agora processada? Há também algum outro conteúdo fora das tags de modelo, que deve permanecer como está, ou seja, algumas tags script e style .

    
por branquito 07.12.2017 / 20:45

1 resposta

1

Eu acredito que você não pode fazer isso com sed . Deve ser possível com awk , mas difícil. python3 parece mais apropriado.

import re
import subprocess
from io import StringIO
from traceback import format_exception_only

PROCESS_COMMAND = ("html2jade",)
TEMPLATE_OPEN_REGEX = re.compile(r"^<template.*>$")
TEMPLATE_CLOSE_REGEX = re.compile(r"^</template>$")

def replace_templates(file_path) :
    out_buffer = StringIO()
    template_buffer = StringIO()

    with open(file_path, "r") as file :
        lines_gen = enumerate(file, 1)
        for (lineno, line) in lines_gen :
            out_buffer.write(line)

            if (TEMPLATE_OPEN_REGEX.match(line)) :
                for (lineno, line) in lines_gen :
                    if (TEMPLATE_OPEN_REGEX.match(line)) :
                        raise ValueError("nested opening tag on line {:d}".format(lineno))
                    elif (TEMPLATE_CLOSE_REGEX.match(line)) :
                        break

                    template_buffer.write(line)
                else :
                    raise ValueError("tag never closed")

                proc = subprocess.run(
                    PROCESS_COMMAND,
                    input=template_buffer.getvalue(),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.DEVNULL,
                    encoding="UTF-8",
                    check=True)

                out_buffer.write(proc.stdout)
                out_buffer.write(line)

                template_buffer.seek(0)
                template_buffer.truncate()
            elif (TEMPLATE_CLOSE_REGEX.match(line)) :
                raise ValueError("closing tag encountered on line {:d}, before opening tag".format(lineno))

    with open(file_path, "w") as file :
        file.write(out_buffer.getvalue())

def main(args) :
    for a in args :
        try :
            replace_templates(a)
        except Exception as ex :
            print("generation failed for file {!r} ({:s})".format(
                 a,
                 format_exception_only(type(ex), ex)[-1].rstrip()))
        else :
            print("file {!r} written".format(a))

if (__name__ == "__main__") :
    from sys import argv

    main(argv[1:])
  • Parece que você ignorou qualquer código de modelo na linha da tag, por isso meu código não manipula isso e faz uma correspondência de linha completa.
  • ValueError é gerado se a abertura e o fechamento da tag do template não forem ordenados corretamente.
  • FileNotFoundError é gerado se o arquivo .vue ou o comando subprocesso não for encontrado.
  • subprocesso.CalledProcessError é gerado se o subprocesso não retornar 0.
  • UnicodeDecodeError é gerado se o subprocesso imprime caracteres não UTF-8.
  • O arquivo não é tocado se ocorrer um erro.
  • A saída completa do arquivo é armazenada em buffer para a RAM.
por 08.12.2017 / 09:58

Tags