]> granicus.if.org Git - postgresql/commitdiff
Fix translation of special characters in psql's LaTeX output modes.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Nov 2018 22:32:51 +0000 (17:32 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
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;