Fix translation of special characters in psql's LaTeX output modes.
authorTom Lane <[email protected]>
Mon, 26 Nov 2018 22:32:51 +0000 (17:32 -0500)
committerTom Lane <[email protected]>
Mon, 26 Nov 2018 22:32:51 +0000 (17:32 -0500)
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.

src/fe_utils/print.c
src/test/regress/expected/psql.out
src/test/regress/sql/psql.sql

index 6b78f0909cdd99e4e7bc4b6c4998a66b67e1aa41..a157a161feae3658142aff942761db29c4f46cc6 100644 (file)
@@ -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:
index f4975464f6a54ad36d8231c5387dd85d6ee2b8cb..775b127121ee8cd0182852900e79c8c04e3fdc80 100644 (file)
@@ -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
index 9ac6c2080419da097a99d95fc55cb3f44e343370..1bb2a6e16d41d44b1ff6035aead27f2d3dff2299 100644 (file)
@@ -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;