2

Is there an easy way to do this? Ideally, a closing bracket would be added to the line lacking the bracket. Is there a SED/AWK answer?

Some lines will read:

\url{http://google.com}

While others:

\url{http://google.com

I'd like to add a closing brace to those lines that contain an opening brace but lack a closing brace.

%%%%% The source file:

%\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}
  • How would you distinguish between a valid situation (like \url that you show) and a \newcommand that is spread across multiple lines, say? – Werner Aug 23 at 4:56
3

You can write a parse in Lua using LPEG which matches balanced braces. Be aware that this is line-based, i.e. if you have constructs where the braces span several lines, this will fail.

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}

Running this with texlua gives

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

It is also possible to automatically add a closing brace on the offending line. To this end, we parse the line and if it fails, we add braces at the end until it succeeds.

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

There are some obvious limitations with this approach, namely that the machine cannot know where exactly the closing brace has to be placed.

test2.tex

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

Running against the example above gives syntactically correct but semantically wrong output:

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

This is not fixable using an automated approach. Only the user can know where the closing brace has to be placed to be semantically correct.

  • Is there a way to automatically add a closing brace at the end of the lines missing them? – Michael Kane Aug 20 at 21:29
  • @MichaelKane See updated answer. – Henri Menke Aug 20 at 21:39
  • This program started running, but would not terminate. Couldn't get through the preamble! See imgur.com/gallery/GbPXIQF – Michael Kane Aug 21 at 21:35
  • @MichaelKane What's on the line where it hangs? – Henri Menke Aug 21 at 21:42
  • That info isn't provided by the 'add missing brace' revision. – Michael Kane Aug 22 at 21:06
-1

I commissioned several programs to fix the issue. Two are Java programs. One is a Javascript program. The other is a python script. Here is a link: https://www12.zippyshare.com/v/9f8cIYpY/file.html

The Javascript and python programs worked for me. Your luck with the Java files depends on the nature of the file you're trying to fix. My file sometimes had two URL's on the same line and this caused the Java programs to gag.

This may have been the reason the lua script proposed by @henrimenke didn't work for me.

  • Please don't post link-only answers. When the link goes offline, the answer becomes useless. – Henri Menke Aug 25 at 2:18
  • How then, does one give programs to the community? – Michael Kane Aug 25 at 16:18
  • @MichaelKane Short codes: here in the posts. TeX related programs: CTAN. And there are code hoster services such as github. That's better than a "common" file sharing service. – Stefan Kottwitz Sep 1 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.