LaTeX writer: fix basic syntax highlight definitions for code role and directive.
[docutils.git] / docutils / test / test_writers / test_latex2e.py
blob97ac130a04e5aeb7d9700f9898aa0e63e622acc3
1 # -*- coding: utf-8 -*-
2 #! /usr/bin/env python
4 # $Id$
5 # Author: engelbert gruber <grubert@users.sourceforge.net>
6 # Copyright: This module has been placed in the public domain.
8 """
9 Tests for latex2e writer.
10 """
12 import string
13 from __init__ import DocutilsTestSupport
15 def suite():
16 settings = {'use_latex_toc': False}
17 s = DocutilsTestSupport.PublishTestSuite('latex', suite_settings=settings)
18 s.generateTests(totest)
19 settings['use_latex_toc'] = True
20 s.generateTests(totest_latex_toc)
21 settings['use_latex_toc'] = False
22 settings['sectnum_xform'] = False
23 s.generateTests(totest_latex_sectnum)
24 settings['sectnum_xform'] = True
25 settings['use_latex_citations'] = True
26 s.generateTests(totest_latex_citations)
27 settings['stylesheet_path'] = 'data/spam,data/ham.tex'
28 s.generateTests(totest_stylesheet)
29 settings['embed_stylesheet'] = True
30 settings['warning_stream'] = ''
31 s.generateTests(totest_stylesheet_embed)
32 return s
34 head_template = string.Template(
35 r"""$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
36 \usepackage{fixltx2e} % LaTeX patches, \textsubscript
37 \usepackage{cmap} % fix search and cut-and-paste in Acrobat
38 $requirements
39 %%% Custom LaTeX preamble
40 $latex_preamble
41 %%% User specified packages and stylesheets
42 $stylesheet
43 %%% Fallback definitions for Docutils-specific commands
44 $fallbacks$pdfsetup
45 $titledata
46 %%% Body
47 \begin{document}
48 """)
50 parts = dict(
51 head_prefix = r"""\documentclass[a4paper]{article}
52 """,
53 requirements = r"""\usepackage{ifthen}
54 \usepackage[T1]{fontenc}
55 \usepackage[utf8]{inputenc}
56 """,
57 latex_preamble = r"""% PDF Standard Fonts
58 \usepackage{mathptmx} % Times
59 \usepackage[scaled=.90]{helvet}
60 \usepackage{courier}
61 """,
62 stylesheet = '',
63 fallbacks = '',
64 fallbacks_highlight = r"""% basic code highlight:
65 \providecommand*\DUrolecomment[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
66 \providecommand*\DUroledeleted[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
67 \providecommand*\DUrolekeyword[1]{\textbf{#1}}
68 \providecommand*\DUrolestring[1]{\textit{#1}}
70 % inline markup (custom roles)
71 % \DUrole{#1}{#2} tries \DUrole#1{#2}
72 \providecommand*{\DUrole}[2]{%
73 \ifcsname DUrole#1\endcsname%
74 \csname DUrole#1\endcsname{#2}%
75 \else% backwards compatibility: try \docutilsrole#1{#2}
76 \ifcsname docutilsrole#1\endcsname%
77 \csname docutilsrole#1\endcsname{#2}%
78 \else%
79 #2%
80 \fi%
81 \fi%
83 """,
84 pdfsetup = r"""
85 % hyperlinks:
86 \ifthenelse{\isundefined{\hypersetup}}{
87 \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
88 \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
89 }{}
90 """,
91 titledata = '')
93 head = head_template.substitute(parts)
95 head_table = head_template.substitute(
96 dict(parts, requirements = parts['requirements'] +
97 r"""\usepackage{longtable,ltcaption,array}
98 \setlength{\extrarowheight}{2pt}
99 \newlength{\DUtablewidth} % internal use in tables
100 """))
102 head_textcomp = head_template.substitute(
103 dict(parts, requirements = parts['requirements'] +
104 r"""\usepackage{textcomp} % text symbol macros
105 """))
107 totest = {}
108 totest_latex_toc = {}
109 totest_latex_sectnum = {}
110 totest_latex_citations = {}
111 totest_stylesheet = {}
112 totest_stylesheet_embed = {}
114 totest['url_chars'] = [
115 ["http://nowhere/url_with%28parens%29",
116 head + r"""
117 \url{http://nowhere/url_with\%28parens\%29}
119 \end{document}
120 """],
123 totest['textcomp'] = [
124 ["2 µm is just 2/1000000 m",
125 head_textcomp + r"""
126 2 µm is just 2/1000000 m
128 \end{document}
129 """],
132 totest['spanish quote'] = [
133 [".. role:: language-es\n\nUnd damit :language-es:`basta`!",
134 head_template.substitute(dict(parts, requirements =
135 r"""\usepackage{ifthen}
136 \usepackage[T1]{fontenc}
137 \usepackage[utf8]{inputenc}
138 \usepackage[spanish,english]{babel}
139 \AtBeginDocument{\shorthandoff{.<>}}
140 """)) + r"""
141 Und damit \foreignlanguage{spanish}{basta}!
143 \end{document}
144 """],
147 totest['code role'] = [
148 [":code:`x=1`",
149 head_template.substitute(dict(parts, requirements = parts['requirements']+
150 r"""\usepackage{color}
151 """, fallbacks = parts['fallbacks_highlight'])) + r"""
152 \texttt{\DUrole{code}{x=1}}
154 \end{document}
155 """],
158 totest['table_of_contents'] = [
159 # input
160 ["""\
161 .. contents:: Table of Contents
163 Title 1
164 =======
165 Paragraph 1.
167 Title 2
168 -------
169 Paragraph 2.
170 """,
171 ## # expected output
172 head_template.substitute(dict(parts,
173 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n',
174 fallbacks=r"""
175 % title for topics, admonitions, unsupported section levels, and sidebar
176 \providecommand*{\DUtitle}[2][class-arg]{%
177 % call \DUtitle#1{#2} if it exists:
178 \ifcsname DUtitle#1\endcsname%
179 \csname DUtitle#1\endcsname{#2}%
180 \else
181 \smallskip\noindent\textbf{#2}\smallskip%
184 """)) + r"""
185 \phantomsection\label{table-of-contents}
186 \pdfbookmark[1]{Table of Contents}{table-of-contents}
187 \DUtitle[contents]{Table of Contents}
189 \begin{list}{}{}
191 \item \hyperref[title-1]{Title 1}
193 \begin{list}{}{}
195 \item \hyperref[title-2]{Title 2}
197 \end{list}
199 \end{list}
202 \section{Title 1%
203 \label{title-1}%
206 Paragraph 1.
209 \subsection{Title 2%
210 \label{title-2}%
213 Paragraph 2.
215 \end{document}
216 """],
220 totest_latex_toc['no_sectnum'] = [
221 # input
222 ["""\
223 .. contents::
225 first section
226 -------------
227 """,
228 ## # expected output
229 head_template.substitute(dict(parts,
230 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
231 )) + r"""
232 \phantomsection\label{contents}
233 \pdfbookmark[1]{Contents}{contents}
234 \tableofcontents
238 \section{first section%
239 \label{first-section}%
242 \end{document}
243 """],
246 totest_latex_toc['sectnum'] = [
247 # input
248 ["""\
249 .. contents::
250 .. sectnum::
252 first section
253 -------------
254 """,
255 ## # expected output
256 head_template.substitute(dict(parts,
257 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
258 )) + r"""
259 \phantomsection\label{contents}
260 \pdfbookmark[1]{Contents}{contents}
261 \tableofcontents
265 \section{1~~~first section%
266 \label{first-section}%
269 \end{document}
270 """],
274 totest_latex_sectnum['no_sectnum'] = [
275 # input
276 ["""\
277 some text
279 first section
280 -------------
281 """,
282 ## # expected output
283 head_template.substitute(dict(parts, requirements = parts['requirements'] +
284 r"""\setcounter{secnumdepth}{0}
285 """)) + r"""
286 some text
289 \section{first section%
290 \label{first-section}%
293 \end{document}
294 """],
297 totest_latex_sectnum['sectnum'] = [
298 # input
299 ["""\
300 .. sectnum::
302 some text
304 first section
305 -------------
306 """,
307 ## # expected output
308 head_template.substitute(dict(parts,
309 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
310 )) + r"""
311 some text
314 \section{first section%
315 \label{first-section}%
318 \end{document}
319 """],
322 totest_latex_citations['citations_with_underscore'] = [
323 # input
324 ["""\
325 Just a test citation [my_cite2006]_.
327 .. [my_cite2006]
328 The underscore is mishandled.
329 """,
330 ## # expected output
331 head + r"""
332 Just a test citation \cite{my_cite2006}.
334 \begin{thebibliography}{my\_cite2006}
335 \bibitem[my\_cite2006]{my_cite2006}{
336 The underscore is mishandled.
338 \end{thebibliography}
340 \end{document}
341 """],
345 totest_latex_citations['adjacent_citations'] = [
346 # input
347 ["""\
348 Two non-citations: [MeYou2007]_[YouMe2007]_.
350 Need to be separated for grouping: [MeYou2007]_ [YouMe2007]_.
352 Two spaces (or anything else) for no grouping: [MeYou2007]_ [YouMe2007]_.
354 But a line break should work: [MeYou2007]_
355 [YouMe2007]_.
357 .. [MeYou2007] not.
358 .. [YouMe2007] important.
359 """,
360 # expected output
361 head + r"""
362 Two non-citations: {[}MeYou2007{]}\_{[}YouMe2007{]}\_.
364 Need to be separated for grouping: \cite{MeYou2007,YouMe2007}.
366 Two spaces (or anything else) for no grouping: \cite{MeYou2007} \cite{YouMe2007}.
368 But a line break should work: \cite{MeYou2007,YouMe2007}.
370 \begin{thebibliography}{MeYou2007}
371 \bibitem[MeYou2007]{MeYou2007}{
372 not.
374 \bibitem[YouMe2007]{YouMe2007}{
375 important.
377 \end{thebibliography}
379 \end{document}
380 """],
384 totest['enumerated_lists'] = [
385 # input
386 ["""\
387 1. Item 1.
388 2. Second to the previous item this one will explain
390 a) nothing.
391 b) or some other.
393 3. Third is
395 (I) having pre and postfixes
396 (II) in roman numerals.
397 """,
398 # expected output
399 head + r"""\newcounter{listcnt0}
400 \begin{list}{\arabic{listcnt0}.}
402 \usecounter{listcnt0}
403 \setlength{\rightmargin}{\leftmargin}
406 \item Item 1.
408 \item Second to the previous item this one will explain
409 \end{list}
411 \begin{quote}
412 \setcounter{listcnt0}{0}
413 \begin{list}{\alph{listcnt0})}
415 \usecounter{listcnt0}
416 \setlength{\rightmargin}{\leftmargin}
419 \item nothing.
421 \item or some other.
422 \end{list}
424 \end{quote}
425 \setcounter{listcnt0}{0}
426 \begin{list}{\arabic{listcnt0}.}
428 \usecounter{listcnt0}
429 \addtocounter{listcnt0}{2}
430 \setlength{\rightmargin}{\leftmargin}
433 \item Third is
434 \end{list}
436 \begin{quote}
437 \setcounter{listcnt0}{0}
438 \begin{list}{(\Roman{listcnt0})}
440 \usecounter{listcnt0}
441 \setlength{\rightmargin}{\leftmargin}
444 \item having pre and postfixes
446 \item in roman numerals.
447 \end{list}
449 \end{quote}
451 \end{document}
452 """],
455 # TODO: need to test for quote replacing if the language uses "ASCII-quotes"
456 # as active character (e.g. de (ngerman)).
459 totest['table_caption'] = [
460 # input
461 ["""\
462 .. table:: Foo
464 +-----+-----+
465 | | |
466 +-----+-----+
467 | | |
468 +-----+-----+
469 """,
470 head_table + r"""
471 \setlength{\DUtablewidth}{\linewidth}
472 \begin{longtable}[c]{|p{0.075\DUtablewidth}|p{0.075\DUtablewidth}|}
473 \caption{Foo}\\
474 \hline
475 & \\
476 \hline
477 & \\
478 \hline
479 \end{longtable}
481 \end{document}
482 """],
485 totest['table_class'] = [
486 # input
487 ["""\
488 .. table::
489 :class: borderless
491 +-----+-----+
492 | 1 | 2 |
493 +-----+-----+
494 | 3 | 4 |
495 +-----+-----+
496 """,
497 head_table + r"""
498 \setlength{\DUtablewidth}{\linewidth}
499 \begin{longtable*}[c]{p{0.075\DUtablewidth}p{0.075\DUtablewidth}}
510 \end{longtable*}
512 \end{document}
513 """],
516 # The "[" needs to be protected (otherwise it will be seen as an
517 # option to "\\", "\item", etc. ).
519 totest['bracket_protection'] = [
520 # input
521 ["""\
524 something before to get a end of line.
527 the empty line gets tested too
529 """,
530 head + r"""%
531 \begin{quote}{\ttfamily \raggedright \noindent
532 something~before~to~get~a~end~of~line.\\
533 {[}\\
535 the~empty~line~gets~tested~too\\
538 \end{quote}
540 \end{document}
541 """],
544 totest['raw'] = [
545 [r""".. raw:: latex
547 $E=mc^2$
549 A paragraph.
551 .. |sub| raw:: latex
553 (some raw text)
555 Foo |sub|
556 same paragraph.
557 """,
558 head + r"""
559 $E=mc^2$
561 A paragraph.
563 Foo (some raw text)
564 same paragraph.
566 \end{document}
567 """],
570 totest['title_with_inline_markup'] = [
571 ["""\
572 This is the *Title*
573 ===================
575 This is the *Subtitle*
576 ----------------------
578 This is a *section title*
579 ~~~~~~~~~~~~~~~~~~~~~~~~~
581 This is the *document*.
582 """,
583 head_template.substitute(dict(parts,
584 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n',
585 pdfsetup=parts['pdfsetup'] + r"""\hypersetup{
586 pdftitle={This is the Title},
588 """, titledata=r"""%%% Title Data
589 \title{\phantomsection%
590 This is the \emph{Title}%
591 \label{this-is-the-title}%
592 \\ % subtitle%
593 \large{This is the \emph{Subtitle}}%
594 \label{this-is-the-subtitle}}
595 \author{}
596 \date{}
597 """)) + r"""\maketitle
600 \section{This is a \emph{section title}%
601 \label{this-is-a-section-title}%
604 This is the \emph{document}.
606 \end{document}
607 """],
610 totest_stylesheet['two-styles'] = [
611 # input
612 ["""two stylesheet links in the header""",
613 head_template.substitute(dict(parts, stylesheet =
614 r"""\usepackage{data/spam}
615 \input{data/ham.tex}
616 """)) + r"""
617 two stylesheet links in the header
619 \end{document}
620 """],
623 totest_stylesheet_embed['two-styles'] = [
624 # input
625 ["""two stylesheets embedded in the header""",
626 head_template.substitute(dict(parts, stylesheet =
627 r"""% Cannot embed stylesheet 'data/spam.sty':
628 % No such file or directory.
629 % embedded stylesheet: data/ham.tex
630 \newcommand{\ham}{wonderful ham}
632 """)) + r"""
633 two stylesheets embedded in the header
635 \end{document}
636 """],
639 if __name__ == '__main__':
640 import unittest
641 unittest.main(defaultTest='suite')