Encuentra líneas que carecen de llaves de cierre

Encuentra líneas que carecen de llaves de cierre

¿Hay una forma fácil de hacer esto? Lo ideal sería agregar un corchete de cierre a la línea que carece del corchete. ¿Existe una respuesta SED/AWK?

Algunas líneas leerán:

\url{http://google.com}

Mientras otros:

\url{http://google.com

Me gustaría agregar una llave de cierre a aquellas líneas que contienen una llave de apertura pero carecen de una llave de cierre.

%%%%% El archivo fuente:

%\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}

Respuesta1

Puede escribir un análisis en Lua usando LPEG que coincida con llaves equilibradas. Tenga en cuenta que esto se basa en líneas, es decir, si tiene construcciones donde las llaves abarcan varias líneas, esto fallará.

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}

Ejecutando esto con texluada

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

También es posible agregar automáticamente una llave de cierre en la línea infractora. Para ello, analizamos la línea y si falla, agregamos llaves al final hasta que tenga éxito.

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

Hay algunas limitaciones obvias con este enfoque, a saber, que la máquina no puede saberdonde exactamentehay que colocar el tirante de cierre.

test2.tex

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

Al ejecutar el ejemplo anterior se obtiene un resultado sintácticamente correcto pero semánticamente incorrecto:

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

Esto no se puede solucionar mediante un enfoque automatizado. Sólo el usuario puede saber dónde se debe colocar la llave de cierre para que sea semánticamente correcta.

Respuesta2

Encargué varios programas para solucionar el problema. Dos son programas Java. Uno es un programa Javascript. El otro es un script en Python. Aquí hay un enlace: https://www12.zippyshare.com/v/9f8cIYpY/file.html

Los programas Javascript y Python funcionaron para mí. Tu suerte con los archivos Java depende de la naturaleza del archivo que estás intentando arreglar. A veces mi archivo tenía dos URL en la misma línea y esto provocaba que los programas Java se atragantaran.

Esta puede haber sido la razón por la que el script lua propuesto por @henrimenke no funcionó para mí.

información relacionada