diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2018-11-26 17:32:51 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2018-11-26 17:32:51 -0500 |
commit | 70d7e507ef9d380bd46345e984f069207de5e24e (patch) | |
tree | 22f1fa97284d9a16c13d43678a5d92e2ff852ebd | |
parent | 95dcb8fc0580c7b1c5f480b3ecaf81c5fc9801ba (diff) | |
download | postgresql-70d7e507ef9d380bd46345e984f069207de5e24e.tar.gz postgresql-70d7e507ef9d380bd46345e984f069207de5e24e.zip |
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 9a98984f4. Back-patch
the code change to all supported versions.
-rw-r--r-- | src/fe_utils/print.c | 36 | ||||
-rw-r--r-- | src/test/regress/expected/psql.out | 132 | ||||
-rw-r--r-- | src/test/regress/sql/psql.sql | 4 |
3 files changed, 98 insertions, 74 deletions
diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index 6b78f0909cd..a157a161fea 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -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: diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index f4975464f6a..775b127121e 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -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 diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 9ac6c208041..1bb2a6e16d4 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -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; |