Encontre linhas sem chaves de fechamento

Encontre linhas sem chaves de fechamento

Existe uma maneira fácil de fazer isso? Idealmente, um colchete de fechamento seria adicionado à linha sem colchete. Existe uma resposta SED/AWK?

Algumas linhas serão lidas:

\url{http://google.com}

Enquanto outros:

\url{http://google.com

Eu gostaria de adicionar uma chave de fechamento às linhas que contêm uma chave de abertura, mas não possuem uma chave de fechamento.

%%%%% O arquivo de origem:

%\usepackage[anythingbreaks]{breakurl}
%\PassOptionsToPackage{hyphens}{url}\usepackage{hyperref}

%\usepackage[hyphens]{url}

\usepackage{url}
\urlstyle{rm}
\makeatletter
\g@addto@macro{\UrlBreaks}{\UrlOrds}
\makeatother


\title{}
\author{}
\date{2019-08-19}
%\sloppy
\begin{document}

Responder1

Você pode escrever uma análise em Lua usando LPEG que corresponda a chaves balanceadas. Esteja ciente de que isso é baseado em linhas, ou seja, se você tiver construções onde as chaves abrangem várias linhas, isso falhará.

test.lua

local lpeg = require("lpeg")
local P, S, V = lpeg.P, lpeg.S, lpeg.V

local function err(match, pos, cap)
    print(match, pos, cap)
end

local rule = P{"text",
    any = 1 - S"{}",
    balanced = "{" * (V"any" + V"balanced")^0 * "}",
    text = V"any" * (V"balanced" + V"any")^0 * P(-1)
}

local path = arg[1] or error("Usage: " .. arg[0] .. " <filename>")
local file = io.open(path, "r")

local n = 1
for line in file:lines() do
    local match = rule:match(line)
    if not match then
        error("Closing } missing on line " .. n)
    end
    n = n + 1
end

test.tex

\documentclass{article}
\usepackage{url}
\begin{document}
\url{http://google.com
\end{document}

Executando isso com texluaofertas

$ texlua test.lua test.tex
test.lua:21: Closing } missing on line 4

Também é possível adicionar automaticamente uma chave de fechamento na linha incorreta. Para isso, analisamos a linha e se ela falhar, adicionamos colchetes no final até que tenha sucesso.

test2.lua

local lpeg = require("lpeg")
local P, S, V = lpeg.P, lpeg.S, lpeg.V

local function err(match, pos, cap)
    print(match, pos, cap)
end

local rule = P{"text",
    any = 1 - S"{}",
    balanced = "{" * (V"any" + V"balanced")^0 * "}",
    text = V"any" * (V"balanced" + V"any")^0 * P(-1)
}

local path = arg[1] or error("Usage: " .. arg[0] .. " <filename>")
local file = io.open(path, "r")

for line in file:lines() do
    local match
    while not match do
        match = rule:match(line)
        if not match then
            line = line .. "}"
        end
    end
    print(line)
end

Existem algumas limitações óbvias nesta abordagem, nomeadamente que a máquina não pode saberonde exatamentea chave de fechamento deve ser colocada.

test2.tex

\documentclass{article}
\usepackage{url}
\begin{document}
Use \url{http://google.com to reach Google search
\end{document}

Executar o exemplo acima fornece uma saída sintaticamente correta, mas semanticamente errada:

$ texlua test2.lua test2.tex
\documentclass{article}
\usepackage{url}
\begin{document}
Use \url{http://google.com to reach Google search}
\end{document}

Isso não pode ser corrigido usando uma abordagem automatizada. Somente o usuário pode saber onde a chave de fechamento deve ser colocada para estar semanticamente correta.

Responder2

Encomendei vários programas para corrigir o problema. Dois são programas Java. Um é um programa Javascript. O outro é um script python. Aqui está um link: https://www12.zippyshare.com/v/9f8cIYpY/file.html

Os programas Javascript e python funcionaram para mim. Sua sorte com os arquivos Java depende da natureza do arquivo que você está tentando corrigir. Meu arquivo às vezes tinha dois URLs na mesma linha e isso fazia com que os programas Java engasgassem.

Pode ter sido esse o motivo pelo qual o script lua proposto por @henrimenke não funcionou para mim.

informação relacionada