Commit 70d7e507 authored by Tom Lane's avatar Tom Lane

Fix translation of special characters in psql's LaTeX output modes.

latex_escaped_print() mistranslated \ and failed to provide any translation
for # ^ and ~, all of which would typically lead to LaTeX document syntax
errors.  In addition it didn't translate < > and |, which would typically
render as unexpected characters.

To some extent this represents shortcomings in ancient versions of LaTeX,
which if memory serves had no easy way to render these control characters
as ASCII text.  But that's been fixed for, um, decades.  In any case there
is no value in emitting guaranteed-to-fail output for these characters.

Noted while fooling with test cases added by commit 9a98984f.  Back-patch
the code change to all supported versions.
parent 95dcb8fc
......@@ -2301,14 +2301,34 @@ latex_escaped_print(const char *in, FILE *fout)
for (p = in; *p; p++)
switch (*p)
{
case '&':
fputs("\\&", fout);
/*
* We convert ASCII characters per the recommendations in
* Scott Pakin's "The Comprehensive LATEX Symbol List",
* available from CTAN. For non-ASCII, you're on your own.
*/
case '#':
fputs("\\#", fout);
break;
case '$':
fputs("\\$", fout);
break;
case '%':
fputs("\\%", fout);
break;
case '$':
fputs("\\$", fout);
case '&':
fputs("\\&", fout);
break;
case '<':
fputs("\\textless{}", fout);
break;
case '>':
fputs("\\textgreater{}", fout);
break;
case '\\':
fputs("\\textbackslash{}", fout);
break;
case '^':
fputs("\\^{}", fout);
break;
case '_':
fputs("\\_", fout);
......@@ -2316,13 +2336,17 @@ latex_escaped_print(const char *in, FILE *fout)
case '{':
fputs("\\{", fout);
break;
case '|':
fputs("\\textbar{}", fout);
break;
case '}':
fputs("\\}", fout);
break;
case '\\':
fputs("\\backslash", fout);
case '~':
fputs("\\~{}", fout);
break;
case '\n':
/* This is not right, but doing it right seems too hard */
fputs("\\\\", fout);
break;
default:
......
......@@ -3443,7 +3443,7 @@ Type & func \\
\noindent
\pset tuples_only false
prepare q as
select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
\pset expanded off
......@@ -3452,8 +3452,8 @@ execute q;
\begin{tabular}{lllr}
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\end{tabular}
\noindent (2 rows) \\
......@@ -3463,8 +3463,8 @@ execute q;
\begin{tabular}{l | l | l | r}
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\end{tabular}
\noindent (2 rows) \\
......@@ -3475,8 +3475,8 @@ execute q;
\hline
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\hline
\end{tabular}
......@@ -3488,9 +3488,9 @@ execute q;
\hline
\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\
\hline
some\backslashmore\_text & \&foo\%\\\{bar\} & & 1 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\
\hline
some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\
\hline
\end{tabular}
......@@ -3501,13 +3501,13 @@ some\backslashmore\_text & \&foo\%\\\{bar\} & & 2 \\
execute q;
\begin{tabular}{cl}
\multicolumn{2}{c}{\textit{Record 1}} \\
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
......@@ -3518,14 +3518,14 @@ execute q;
\begin{tabular}{c|l}
\multicolumn{2}{c}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
......@@ -3537,15 +3537,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
......@@ -3558,15 +3558,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
......@@ -3667,7 +3667,7 @@ Type & func \\
\noindent
\pset tuples_only false
prepare q as
select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
\pset expanded off
......@@ -3680,16 +3680,16 @@ execute q;
\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\
\midrule
\endhead
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
......@@ -3704,16 +3704,16 @@ execute q;
\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\
\midrule
\endhead
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
......@@ -3734,16 +3734,16 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
......@@ -3763,17 +3763,17 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\hline
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
......@@ -3794,17 +3794,17 @@ execute q;
\endfoot
\bottomrule
\endlastfoot
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
\raggedright{1} \tabularnewline
\hline
\raggedright{some\backslashmore\_text}
\raggedright{some\textbackslash{}more\_text}
&
\raggedright{ \&foo\%\\\{bar\}}
\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}}
&
\raggedright{ }
&
......@@ -3817,13 +3817,13 @@ execute q;
execute q;
\begin{tabular}{cl}
\multicolumn{2}{c}{\textit{Record 1}} \\
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
......@@ -3834,14 +3834,14 @@ execute q;
\begin{tabular}{c|l}
\multicolumn{2}{c}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\multicolumn{2}{c}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\end{tabular}
......@@ -3853,15 +3853,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
......@@ -3874,15 +3874,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
......@@ -3895,15 +3895,15 @@ execute q;
\hline
\multicolumn{2}{|c|}{\textit{Record 1}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 1 \\
\hline
\multicolumn{2}{|c|}{\textit{Record 2}} \\
\hline
a\$title & some\backslashmore\_text \\
junk & \&foo\%\\\{bar\} \\
a\$title & some\textbackslash{}more\_text \\
junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\
empty & \\
int & 2 \\
\hline
......
......@@ -611,7 +611,7 @@ deallocate q;
\pset tuples_only false
prepare q as
select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
......@@ -660,7 +660,7 @@ deallocate q;
\pset tuples_only false
prepare q as
select 'some\more_text' as "a$title", E' &foo%\n{bar}' as "junk",
select 'some\more_text' as "a$title", E' #<foo>%&^~|\n{bar}' as "junk",
' ' as "empty", n as int
from generate_series(1,2) as n;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment