1""" 2 test_build_latex 3 ~~~~~~~~~~~~~~~~ 4 5 Test the build process with LaTeX builder with the test root. 6 7 :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. 8 :license: BSD, see LICENSE for details. 9""" 10 11import os 12import re 13import subprocess 14from itertools import product 15from shutil import copyfile 16from subprocess import PIPE, CalledProcessError 17 18import pytest 19 20from sphinx.builders.latex import default_latex_documents 21from sphinx.config import Config 22from sphinx.errors import SphinxError 23from sphinx.testing.util import strip_escseq 24from sphinx.util import docutils 25from sphinx.util.osutil import cd, ensuredir 26from sphinx.writers.latex import LaTeXTranslator 27 28from .test_build_html import ENV_WARNINGS 29 30LATEX_ENGINES = ['pdflatex', 'lualatex', 'xelatex'] 31DOCCLASSES = ['howto', 'manual'] 32STYLEFILES = ['article.cls', 'fancyhdr.sty', 'titlesec.sty', 'amsmath.sty', 33 'framed.sty', 'color.sty', 'fancyvrb.sty', 34 'fncychap.sty', 'geometry.sty', 'kvoptions.sty', 'hyperref.sty'] 35 36LATEX_WARNINGS = ENV_WARNINGS + """\ 37%(root)s/index.rst:\\d+: WARNING: unknown option: &option 38%(root)s/index.rst:\\d+: WARNING: citation not found: missing 39%(root)s/index.rst:\\d+: WARNING: a suitable image for latex builder not found: foo.\\* 40%(root)s/index.rst:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped. 41""" 42 43 44# only run latex if all needed packages are there 45def kpsetest(*filenames): 46 try: 47 subprocess.run(['kpsewhich'] + list(filenames), stdout=PIPE, stderr=PIPE, check=True) 48 return True 49 except (OSError, CalledProcessError): 50 return False # command not found or exit with non-zero 51 52 53# compile latex document with app.config.latex_engine 54def compile_latex_document(app, filename='python.tex'): 55 # now, try to run latex over it 56 try: 57 with cd(app.outdir): 58 ensuredir(app.config.latex_engine) 59 # keep a copy of latex file for this engine in case test fails 60 copyfile(filename, app.config.latex_engine + '/' + filename) 61 args = [app.config.latex_engine, 62 '--halt-on-error', 63 '--interaction=nonstopmode', 64 '-output-directory=%s' % app.config.latex_engine, 65 filename] 66 subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) 67 except OSError as exc: # most likely the latex executable was not found 68 raise pytest.skip.Exception from exc 69 except CalledProcessError as exc: 70 print(exc.stdout) 71 print(exc.stderr) 72 assert False, '%s exited with return code %s' % (app.config.latex_engine, 73 exc.returncode) 74 75 76def skip_if_requested(testfunc): 77 if 'SKIP_LATEX_BUILD' in os.environ: 78 msg = 'Skip LaTeX builds because SKIP_LATEX_BUILD is set' 79 return pytest.mark.skipif(True, reason=msg)(testfunc) 80 else: 81 return testfunc 82 83 84def skip_if_stylefiles_notfound(testfunc): 85 if kpsetest(*STYLEFILES) is False: 86 msg = 'not running latex, the required styles do not seem to be installed' 87 return pytest.mark.skipif(True, reason=msg)(testfunc) 88 else: 89 return testfunc 90 91 92@skip_if_requested 93@skip_if_stylefiles_notfound 94@pytest.mark.parametrize( 95 "engine,docclass", 96 product(LATEX_ENGINES, DOCCLASSES), 97) 98@pytest.mark.sphinx('latex') 99def test_build_latex_doc(app, status, warning, engine, docclass): 100 app.config.latex_engine = engine 101 app.config.latex_documents = [app.config.latex_documents[0][:4] + (docclass,)] 102 app.builder.init() 103 104 LaTeXTranslator.ignore_missing_images = True 105 app.builder.build_all() 106 107 # file from latex_additional_files 108 assert (app.outdir / 'svgimg.svg').isfile() 109 110 compile_latex_document(app, 'sphinxtests.tex') 111 112 113@pytest.mark.sphinx('latex') 114def test_writer(app, status, warning): 115 app.builder.build_all() 116 result = (app.outdir / 'sphinxtests.tex').read_text() 117 118 assert ('\\begin{sphinxfigure-in-table}\n\\centering\n\\capstart\n' 119 '\\noindent\\sphinxincludegraphics{{img}.png}\n' 120 '\\sphinxfigcaption{figure in table}\\label{\\detokenize{markup:id8}}' 121 '\\end{sphinxfigure-in-table}\\relax' in result) 122 123 assert ('\\begin{wrapfigure}{r}{0pt}\n\\centering\n' 124 '\\noindent\\sphinxincludegraphics{{rimg}.png}\n' 125 '\\caption{figure with align option}\\label{\\detokenize{markup:id9}}' 126 '\\end{wrapfigure}' in result) 127 128 assert ('\\begin{wrapfigure}{r}{0.500\\linewidth}\n\\centering\n' 129 '\\noindent\\sphinxincludegraphics{{rimg}.png}\n' 130 '\\caption{figure with align \\& figwidth option}' 131 '\\label{\\detokenize{markup:id10}}' 132 '\\end{wrapfigure}' in result) 133 134 assert ('\\begin{wrapfigure}{r}{3cm}\n\\centering\n' 135 '\\noindent\\sphinxincludegraphics[width=3cm]{{rimg}.png}\n' 136 '\\caption{figure with align \\& width option}' 137 '\\label{\\detokenize{markup:id11}}' 138 '\\end{wrapfigure}' in result) 139 140 assert 'Footnotes' not in result 141 142 143@pytest.mark.sphinx('latex', testroot='warnings', freshenv=True) 144def test_latex_warnings(app, status, warning): 145 app.builder.build_all() 146 147 warnings = strip_escseq(re.sub(re.escape(os.sep) + '{1,2}', '/', warning.getvalue())) 148 warnings_exp = LATEX_WARNINGS % { 149 'root': re.escape(app.srcdir.replace(os.sep, '/'))} 150 assert re.match(warnings_exp + '$', warnings), \ 151 'Warnings don\'t match:\n' + \ 152 '--- Expected (regex):\n' + warnings_exp + \ 153 '--- Got:\n' + warnings 154 155 156@pytest.mark.sphinx('latex', testroot='basic') 157def test_latex_basic(app, status, warning): 158 app.builder.build_all() 159 result = (app.outdir / 'test.tex').read_text() 160 print(result) 161 print(status.getvalue()) 162 print(warning.getvalue()) 163 assert r'\title{The basic Sphinx documentation for testing}' in result 164 assert r'\release{}' in result 165 assert r'\renewcommand{\releasename}{}' in result 166 167 168@pytest.mark.sphinx('latex', testroot='basic', 169 confoverrides={ 170 'latex_documents': [('index', 'test.tex', 'title', 'author', 'manual')] 171 }) 172def test_latex_basic_manual(app, status, warning): 173 app.builder.build_all() 174 result = (app.outdir / 'test.tex').read_text(encoding='utf8') 175 print(result) 176 assert r'\def\sphinxdocclass{report}' in result 177 assert r'\documentclass[letterpaper,10pt,english]{sphinxmanual}' in result 178 179 180@pytest.mark.sphinx('latex', testroot='basic', 181 confoverrides={ 182 'latex_documents': [('index', 'test.tex', 'title', 'author', 'howto')] 183 }) 184def test_latex_basic_howto(app, status, warning): 185 app.builder.build_all() 186 result = (app.outdir / 'test.tex').read_text(encoding='utf8') 187 print(result) 188 assert r'\def\sphinxdocclass{article}' in result 189 assert r'\documentclass[letterpaper,10pt,english]{sphinxhowto}' in result 190 191 192@pytest.mark.sphinx('latex', testroot='basic', 193 confoverrides={ 194 'language': 'ja', 195 'latex_documents': [('index', 'test.tex', 'title', 'author', 'manual')] 196 }) 197def test_latex_basic_manual_ja(app, status, warning): 198 app.builder.build_all() 199 result = (app.outdir / 'test.tex').read_text(encoding='utf8') 200 print(result) 201 assert r'\def\sphinxdocclass{jsbook}' in result 202 assert r'\documentclass[letterpaper,10pt,dvipdfmx]{sphinxmanual}' in result 203 204 205@pytest.mark.sphinx('latex', testroot='basic', 206 confoverrides={ 207 'language': 'ja', 208 'latex_documents': [('index', 'test.tex', 'title', 'author', 'howto')] 209 }) 210def test_latex_basic_howto_ja(app, status, warning): 211 app.builder.build_all() 212 result = (app.outdir / 'test.tex').read_text(encoding='utf8') 213 print(result) 214 assert r'\def\sphinxdocclass{jreport}' in result 215 assert r'\documentclass[letterpaper,10pt,dvipdfmx]{sphinxhowto}' in result 216 217 218@pytest.mark.sphinx('latex', testroot='latex-theme') 219def test_latex_theme(app, status, warning): 220 app.builder.build_all() 221 result = (app.outdir / 'python.tex').read_text(encoding='utf8') 222 print(result) 223 assert r'\def\sphinxdocclass{book}' in result 224 assert r'\documentclass[a4paper,12pt,english]{sphinxbook}' in result 225 226 227@pytest.mark.sphinx('latex', testroot='latex-theme', 228 confoverrides={'latex_elements': {'papersize': 'b5paper', 229 'pointsize': '9pt'}}) 230def test_latex_theme_papersize(app, status, warning): 231 app.builder.build_all() 232 result = (app.outdir / 'python.tex').read_text(encoding='utf8') 233 print(result) 234 assert r'\def\sphinxdocclass{book}' in result 235 assert r'\documentclass[b5paper,9pt,english]{sphinxbook}' in result 236 237 238@pytest.mark.sphinx('latex', testroot='latex-theme', 239 confoverrides={'latex_theme_options': {'papersize': 'b5paper', 240 'pointsize': '9pt'}}) 241def test_latex_theme_options(app, status, warning): 242 app.builder.build_all() 243 result = (app.outdir / 'python.tex').read_text(encoding='utf8') 244 print(result) 245 assert r'\def\sphinxdocclass{book}' in result 246 assert r'\documentclass[b5paper,9pt,english]{sphinxbook}' in result 247 248 249@pytest.mark.sphinx('latex', testroot='basic', confoverrides={'language': 'zh'}) 250def test_latex_additional_settings_for_language_code(app, status, warning): 251 app.builder.build_all() 252 result = (app.outdir / 'test.tex').read_text() 253 print(result) 254 print(status.getvalue()) 255 print(warning.getvalue()) 256 assert r'\usepackage{xeCJK}' in result 257 258 259@pytest.mark.sphinx('latex', testroot='basic', confoverrides={'language': 'el'}) 260def test_latex_additional_settings_for_greek(app, status, warning): 261 app.builder.build_all() 262 result = (app.outdir / 'test.tex').read_text() 263 print(result) 264 print(status.getvalue()) 265 print(warning.getvalue()) 266 assert '\\usepackage{polyglossia}\n\\setmainlanguage{greek}' in result 267 assert '\\newfontfamily\\greekfonttt{FreeMono}' in result 268 269 270@pytest.mark.sphinx('latex', testroot='latex-title') 271def test_latex_title_after_admonitions(app, status, warning): 272 app.builder.build_all() 273 result = (app.outdir / 'test.tex').read_text() 274 print(result) 275 print(status.getvalue()) 276 print(warning.getvalue()) 277 assert '\\title{test\\sphinxhyphen{}latex\\sphinxhyphen{}title}' in result 278 279 280@pytest.mark.sphinx('latex', testroot='basic', 281 confoverrides={'release': '1.0'}) 282def test_latex_release(app, status, warning): 283 app.builder.build_all() 284 result = (app.outdir / 'test.tex').read_text() 285 print(result) 286 print(status.getvalue()) 287 print(warning.getvalue()) 288 assert r'\release{1.0}' in result 289 assert r'\renewcommand{\releasename}{Release}' in result 290 291 292@pytest.mark.sphinx('latex', testroot='numfig', 293 confoverrides={'numfig': True}) 294def test_numref(app, status, warning): 295 app.builder.build_all() 296 result = (app.outdir / 'python.tex').read_text() 297 print(result) 298 print(status.getvalue()) 299 print(warning.getvalue()) 300 assert ('\\hyperref[\\detokenize{index:fig1}]' 301 '{Fig.\\@ \\ref{\\detokenize{index:fig1}}}') in result 302 assert ('\\hyperref[\\detokenize{baz:fig22}]' 303 '{Figure\\ref{\\detokenize{baz:fig22}}}') in result 304 assert ('\\hyperref[\\detokenize{index:table-1}]' 305 '{Table \\ref{\\detokenize{index:table-1}}}') in result 306 assert ('\\hyperref[\\detokenize{baz:table22}]' 307 '{Table:\\ref{\\detokenize{baz:table22}}}') in result 308 assert ('\\hyperref[\\detokenize{index:code-1}]' 309 '{Listing \\ref{\\detokenize{index:code-1}}}') in result 310 assert ('\\hyperref[\\detokenize{baz:code22}]' 311 '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result 312 assert ('\\hyperref[\\detokenize{foo:foo}]' 313 '{Section \\ref{\\detokenize{foo:foo}}}') in result 314 assert ('\\hyperref[\\detokenize{bar:bar-a}]' 315 '{Section \\ref{\\detokenize{bar:bar-a}}}') in result 316 assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} ' 317 '\\nameref{\\detokenize{index:fig1}}}') in result 318 assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} ' 319 '\\nameref{\\detokenize{foo:foo}}}') in result 320 321 # sphinxmessages.sty 322 result = (app.outdir / 'sphinxmessages.sty').read_text() 323 print(result) 324 assert r'\addto\captionsenglish{\renewcommand{\figurename}{Fig.\@{} }}' in result 325 assert r'\addto\captionsenglish{\renewcommand{\tablename}{Table }}' in result 326 assert r'\addto\captionsenglish{\renewcommand{\literalblockname}{Listing}}' in result 327 328 329@pytest.mark.sphinx( 330 'latex', testroot='numfig', 331 confoverrides={'numfig': True, 332 'numfig_format': {'figure': 'Figure:%s', 333 'table': 'Tab_%s', 334 'code-block': 'Code-%s', 335 'section': 'SECTION-%s'}}) 336def test_numref_with_prefix1(app, status, warning): 337 app.builder.build_all() 338 result = (app.outdir / 'python.tex').read_text() 339 print(result) 340 print(status.getvalue()) 341 print(warning.getvalue()) 342 assert '\\ref{\\detokenize{index:fig1}}' in result 343 assert '\\ref{\\detokenize{baz:fig22}}' in result 344 assert '\\ref{\\detokenize{index:table-1}}' in result 345 assert '\\ref{\\detokenize{baz:table22}}' in result 346 assert '\\ref{\\detokenize{index:code-1}}' in result 347 assert '\\ref{\\detokenize{baz:code22}}' in result 348 assert ('\\hyperref[\\detokenize{index:fig1}]' 349 '{Figure:\\ref{\\detokenize{index:fig1}}}') in result 350 assert ('\\hyperref[\\detokenize{baz:fig22}]' 351 '{Figure\\ref{\\detokenize{baz:fig22}}}') in result 352 assert ('\\hyperref[\\detokenize{index:table-1}]' 353 '{Tab\\_\\ref{\\detokenize{index:table-1}}}') in result 354 assert ('\\hyperref[\\detokenize{baz:table22}]' 355 '{Table:\\ref{\\detokenize{baz:table22}}}') in result 356 assert ('\\hyperref[\\detokenize{index:code-1}]' 357 '{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}}}') in result 358 assert ('\\hyperref[\\detokenize{baz:code22}]' 359 '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result 360 assert ('\\hyperref[\\detokenize{foo:foo}]' 361 '{SECTION\\sphinxhyphen{}\\ref{\\detokenize{foo:foo}}}') in result 362 assert ('\\hyperref[\\detokenize{bar:bar-a}]' 363 '{SECTION\\sphinxhyphen{}\\ref{\\detokenize{bar:bar-a}}}') in result 364 assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} ' 365 '\\nameref{\\detokenize{index:fig1}}}') in result 366 assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} ' 367 '\\nameref{\\detokenize{foo:foo}}}') in result 368 369 # sphinxmessages.sty 370 result = (app.outdir / 'sphinxmessages.sty').read_text() 371 print(result) 372 assert r'\addto\captionsenglish{\renewcommand{\figurename}{Figure:}}' in result 373 assert r'\addto\captionsenglish{\renewcommand{\tablename}{Tab\_}}' in result 374 assert r'\addto\captionsenglish{\renewcommand{\literalblockname}{Code-}}' in result 375 376 377@pytest.mark.sphinx( 378 'latex', testroot='numfig', 379 confoverrides={'numfig': True, 380 'numfig_format': {'figure': 'Figure:%s.', 381 'table': 'Tab_%s:', 382 'code-block': 'Code-%s | ', 383 'section': 'SECTION_%s_'}}) 384def test_numref_with_prefix2(app, status, warning): 385 app.builder.build_all() 386 result = (app.outdir / 'python.tex').read_text() 387 print(result) 388 print(status.getvalue()) 389 print(warning.getvalue()) 390 assert ('\\hyperref[\\detokenize{index:fig1}]' 391 '{Figure:\\ref{\\detokenize{index:fig1}}.\\@}') in result 392 assert ('\\hyperref[\\detokenize{baz:fig22}]' 393 '{Figure\\ref{\\detokenize{baz:fig22}}}') in result 394 assert ('\\hyperref[\\detokenize{index:table-1}]' 395 '{Tab\\_\\ref{\\detokenize{index:table-1}}:}') in result 396 assert ('\\hyperref[\\detokenize{baz:table22}]' 397 '{Table:\\ref{\\detokenize{baz:table22}}}') in result 398 assert ('\\hyperref[\\detokenize{index:code-1}]{Code\\sphinxhyphen{}\\ref{\\detokenize{index:code-1}} ' 399 '| }') in result 400 assert ('\\hyperref[\\detokenize{baz:code22}]' 401 '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result 402 assert ('\\hyperref[\\detokenize{foo:foo}]' 403 '{SECTION\\_\\ref{\\detokenize{foo:foo}}\\_}') in result 404 assert ('\\hyperref[\\detokenize{bar:bar-a}]' 405 '{SECTION\\_\\ref{\\detokenize{bar:bar-a}}\\_}') in result 406 assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} ' 407 '\\nameref{\\detokenize{index:fig1}}}') in result 408 assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} ' 409 '\\nameref{\\detokenize{foo:foo}}}') in result 410 411 # sphinxmessages.sty 412 result = (app.outdir / 'sphinxmessages.sty').read_text() 413 print(result) 414 assert r'\addto\captionsenglish{\renewcommand{\figurename}{Figure:}}' in result 415 assert r'\def\fnum@figure{\figurename\thefigure{}.}' in result 416 assert r'\addto\captionsenglish{\renewcommand{\tablename}{Tab\_}}' in result 417 assert r'\def\fnum@table{\tablename\thetable{}:}' in result 418 assert r'\addto\captionsenglish{\renewcommand{\literalblockname}{Code-}}' in result 419 420 421@pytest.mark.sphinx( 422 'latex', testroot='numfig', 423 confoverrides={'numfig': True, 'language': 'ja'}) 424def test_numref_with_language_ja(app, status, warning): 425 app.builder.build_all() 426 result = (app.outdir / 'python.tex').read_text() 427 print(result) 428 print(status.getvalue()) 429 print(warning.getvalue()) 430 assert ('\\hyperref[\\detokenize{index:fig1}]' 431 '{\u56f3 \\ref{\\detokenize{index:fig1}}}') in result 432 assert ('\\hyperref[\\detokenize{baz:fig22}]' 433 '{Figure\\ref{\\detokenize{baz:fig22}}}') in result 434 assert ('\\hyperref[\\detokenize{index:table-1}]' 435 '{\u8868 \\ref{\\detokenize{index:table-1}}}') in result 436 assert ('\\hyperref[\\detokenize{baz:table22}]' 437 '{Table:\\ref{\\detokenize{baz:table22}}}') in result 438 assert ('\\hyperref[\\detokenize{index:code-1}]' 439 '{\u30ea\u30b9\u30c8 \\ref{\\detokenize{index:code-1}}}') in result 440 assert ('\\hyperref[\\detokenize{baz:code22}]' 441 '{Code\\sphinxhyphen{}\\ref{\\detokenize{baz:code22}}}') in result 442 assert ('\\hyperref[\\detokenize{foo:foo}]' 443 '{\\ref{\\detokenize{foo:foo}} \u7ae0}') in result 444 assert ('\\hyperref[\\detokenize{bar:bar-a}]' 445 '{\\ref{\\detokenize{bar:bar-a}} \u7ae0}') in result 446 assert ('\\hyperref[\\detokenize{index:fig1}]{Fig.\\ref{\\detokenize{index:fig1}} ' 447 '\\nameref{\\detokenize{index:fig1}}}') in result 448 assert ('\\hyperref[\\detokenize{foo:foo}]{Sect.\\ref{\\detokenize{foo:foo}} ' 449 '\\nameref{\\detokenize{foo:foo}}}') in result 450 451 # sphinxmessages.sty 452 result = (app.outdir / 'sphinxmessages.sty').read_text() 453 print(result) 454 assert '\\@iden{\\renewcommand{\\figurename}{図 }}' in result 455 assert '\\@iden{\\renewcommand{\\tablename}{表 }}' in result 456 assert '\\@iden{\\renewcommand{\\literalblockname}{リスト}}' in result 457 458 459@pytest.mark.sphinx('latex', testroot='latex-numfig') 460def test_latex_obey_numfig_is_false(app, status, warning): 461 app.builder.build_all() 462 463 result = (app.outdir / 'SphinxManual.tex').read_text() 464 assert '\\usepackage{sphinx}' in result 465 466 result = (app.outdir / 'SphinxHowTo.tex').read_text() 467 assert '\\usepackage{sphinx}' in result 468 469 470@pytest.mark.sphinx( 471 'latex', testroot='latex-numfig', 472 confoverrides={'numfig': True, 'numfig_secnum_depth': 0}) 473def test_latex_obey_numfig_secnum_depth_is_zero(app, status, warning): 474 app.builder.build_all() 475 476 result = (app.outdir / 'SphinxManual.tex').read_text() 477 assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result 478 479 result = (app.outdir / 'SphinxHowTo.tex').read_text() 480 assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result 481 482 483@pytest.mark.sphinx( 484 'latex', testroot='latex-numfig', 485 confoverrides={'numfig': True, 'numfig_secnum_depth': 2}) 486def test_latex_obey_numfig_secnum_depth_is_two(app, status, warning): 487 app.builder.build_all() 488 489 result = (app.outdir / 'SphinxManual.tex').read_text() 490 assert '\\usepackage[,numfigreset=2,mathnumfig]{sphinx}' in result 491 492 result = (app.outdir / 'SphinxHowTo.tex').read_text() 493 assert '\\usepackage[,numfigreset=3,mathnumfig]{sphinx}' in result 494 495 496@pytest.mark.sphinx( 497 'latex', testroot='latex-numfig', 498 confoverrides={'numfig': True, 'math_numfig': False}) 499def test_latex_obey_numfig_but_math_numfig_false(app, status, warning): 500 app.builder.build_all() 501 502 result = (app.outdir / 'SphinxManual.tex').read_text() 503 assert '\\usepackage[,numfigreset=1]{sphinx}' in result 504 505 result = (app.outdir / 'SphinxHowTo.tex').read_text() 506 assert '\\usepackage[,numfigreset=2]{sphinx}' in result 507 508 509@pytest.mark.sphinx('latex', testroot='basic') 510def test_latex_add_latex_package(app, status, warning): 511 app.add_latex_package('foo') 512 app.add_latex_package('bar', 'baz') 513 app.builder.build_all() 514 result = (app.outdir / 'test.tex').read_text() 515 assert '\\usepackage{foo}' in result 516 assert '\\usepackage[baz]{bar}' in result 517 518 519@pytest.mark.sphinx('latex', testroot='latex-babel') 520def test_babel_with_no_language_settings(app, status, warning): 521 app.builder.build_all() 522 result = (app.outdir / 'python.tex').read_text() 523 print(result) 524 print(status.getvalue()) 525 print(warning.getvalue()) 526 assert '\\documentclass[letterpaper,10pt,english]{sphinxmanual}' in result 527 assert '\\usepackage{babel}' in result 528 assert '\\usepackage{times}' in result 529 assert '\\usepackage[Bjarne]{fncychap}' in result 530 assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n' 531 in result) 532 assert '\\shorthandoff' not in result 533 534 # sphinxmessages.sty 535 result = (app.outdir / 'sphinxmessages.sty').read_text() 536 print(result) 537 assert r'\def\pageautorefname{page}' in result 538 assert r'\addto\captionsenglish{\renewcommand{\figurename}{Fig.\@{} }}' in result 539 assert r'\addto\captionsenglish{\renewcommand{\tablename}{Table.\@{} }}' in result 540 541 542@pytest.mark.sphinx( 543 'latex', testroot='latex-babel', 544 confoverrides={'language': 'de'}) 545def test_babel_with_language_de(app, status, warning): 546 app.builder.build_all() 547 result = (app.outdir / 'python.tex').read_text() 548 print(result) 549 print(status.getvalue()) 550 print(warning.getvalue()) 551 assert '\\documentclass[letterpaper,10pt,ngerman]{sphinxmanual}' in result 552 assert '\\usepackage{babel}' in result 553 assert '\\usepackage{times}' in result 554 assert '\\usepackage[Sonny]{fncychap}' in result 555 assert ('\\addto\\captionsngerman{\\renewcommand{\\contentsname}{Table of content}}\n' 556 in result) 557 assert '\\shorthandoff{"}' in result 558 559 # sphinxmessages.sty 560 result = (app.outdir / 'sphinxmessages.sty').read_text() 561 print(result) 562 assert r'\def\pageautorefname{Seite}' in result 563 assert r'\addto\captionsngerman{\renewcommand{\figurename}{Fig.\@{} }}' in result 564 assert r'\addto\captionsngerman{\renewcommand{\tablename}{Table.\@{} }}' in result 565 566 567@pytest.mark.sphinx( 568 'latex', testroot='latex-babel', 569 confoverrides={'language': 'ru'}) 570def test_babel_with_language_ru(app, status, warning): 571 app.builder.build_all() 572 result = (app.outdir / 'python.tex').read_text() 573 print(result) 574 print(status.getvalue()) 575 print(warning.getvalue()) 576 assert '\\documentclass[letterpaper,10pt,russian]{sphinxmanual}' in result 577 assert '\\usepackage{babel}' in result 578 assert '\\usepackage{times}' not in result 579 assert '\\usepackage[Sonny]{fncychap}' in result 580 assert ('\\addto\\captionsrussian{\\renewcommand{\\contentsname}{Table of content}}\n' 581 in result) 582 assert '\\shorthandoff{"}' in result 583 584 # sphinxmessages.sty 585 result = (app.outdir / 'sphinxmessages.sty').read_text() 586 print(result) 587 assert r'\def\pageautorefname{страница}' in result 588 assert r'\addto\captionsrussian{\renewcommand{\figurename}{Fig.\@{} }}' in result 589 assert r'\addto\captionsrussian{\renewcommand{\tablename}{Table.\@{} }}' in result 590 591 592@pytest.mark.sphinx( 593 'latex', testroot='latex-babel', 594 confoverrides={'language': 'tr'}) 595def test_babel_with_language_tr(app, status, warning): 596 app.builder.build_all() 597 result = (app.outdir / 'python.tex').read_text() 598 print(result) 599 print(status.getvalue()) 600 print(warning.getvalue()) 601 assert '\\documentclass[letterpaper,10pt,turkish]{sphinxmanual}' in result 602 assert '\\usepackage{babel}' in result 603 assert '\\usepackage{times}' in result 604 assert '\\usepackage[Sonny]{fncychap}' in result 605 assert ('\\addto\\captionsturkish{\\renewcommand{\\contentsname}{Table of content}}\n' 606 in result) 607 assert '\\shorthandoff{=}' in result 608 609 # sphinxmessages.sty 610 result = (app.outdir / 'sphinxmessages.sty').read_text() 611 print(result) 612 assert r'\def\pageautorefname{sayfa}' in result 613 assert r'\addto\captionsturkish{\renewcommand{\figurename}{Fig.\@{} }}' in result 614 assert r'\addto\captionsturkish{\renewcommand{\tablename}{Table.\@{} }}' in result 615 616 617@pytest.mark.sphinx( 618 'latex', testroot='latex-babel', 619 confoverrides={'language': 'ja'}) 620def test_babel_with_language_ja(app, status, warning): 621 app.builder.build_all() 622 result = (app.outdir / 'python.tex').read_text() 623 print(result) 624 print(status.getvalue()) 625 print(warning.getvalue()) 626 assert '\\documentclass[letterpaper,10pt,dvipdfmx]{sphinxmanual}' in result 627 assert '\\usepackage{babel}' not in result 628 assert '\\usepackage{times}' in result 629 assert '\\usepackage[Sonny]{fncychap}' not in result 630 assert '\\renewcommand{\\contentsname}{Table of content}\n' in result 631 assert '\\shorthandoff' not in result 632 633 # sphinxmessages.sty 634 result = (app.outdir / 'sphinxmessages.sty').read_text() 635 print(result) 636 assert r'\def\pageautorefname{ページ}' in result 637 assert '\\@iden{\\renewcommand{\\figurename}{Fig.\\@{} }}' in result 638 assert '\\@iden{\\renewcommand{\\tablename}{Table.\\@{} }}' in result 639 640 641@pytest.mark.sphinx( 642 'latex', testroot='latex-babel', 643 confoverrides={'language': 'unknown'}) 644def test_babel_with_unknown_language(app, status, warning): 645 app.builder.build_all() 646 result = (app.outdir / 'python.tex').read_text() 647 print(result) 648 print(status.getvalue()) 649 print(warning.getvalue()) 650 assert '\\documentclass[letterpaper,10pt,english]{sphinxmanual}' in result 651 assert '\\usepackage{babel}' in result 652 assert '\\usepackage{times}' in result 653 assert '\\usepackage[Sonny]{fncychap}' in result 654 assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n' 655 in result) 656 assert '\\shorthandoff' in result 657 658 assert "WARNING: no Babel option known for language 'unknown'" in warning.getvalue() 659 660 # sphinxmessages.sty 661 result = (app.outdir / 'sphinxmessages.sty').read_text() 662 print(result) 663 assert r'\def\pageautorefname{page}' in result 664 assert r'\addto\captionsenglish{\renewcommand{\figurename}{Fig.\@{} }}' in result 665 assert r'\addto\captionsenglish{\renewcommand{\tablename}{Table.\@{} }}' in result 666 667 668@pytest.mark.sphinx( 669 'latex', testroot='latex-babel', 670 confoverrides={'language': 'de', 'latex_engine': 'lualatex'}) 671def test_polyglossia_with_language_de(app, status, warning): 672 app.builder.build_all() 673 result = (app.outdir / 'python.tex').read_text() 674 print(result) 675 print(status.getvalue()) 676 print(warning.getvalue()) 677 assert '\\documentclass[letterpaper,10pt,german]{sphinxmanual}' in result 678 assert '\\usepackage{polyglossia}' in result 679 assert '\\setmainlanguage[spelling=new]{german}' in result 680 assert '\\usepackage{times}' not in result 681 assert '\\usepackage[Sonny]{fncychap}' in result 682 assert ('\\addto\\captionsgerman{\\renewcommand{\\contentsname}{Table of content}}\n' 683 in result) 684 assert '\\shorthandoff' not in result 685 686 # sphinxmessages.sty 687 result = (app.outdir / 'sphinxmessages.sty').read_text() 688 print(result) 689 assert r'\def\pageautorefname{Seite}' in result 690 assert r'\addto\captionsgerman{\renewcommand{\figurename}{Fig.\@{} }}' in result 691 assert r'\addto\captionsgerman{\renewcommand{\tablename}{Table.\@{} }}' in result 692 693 694@pytest.mark.sphinx( 695 'latex', testroot='latex-babel', 696 confoverrides={'language': 'de-1901', 'latex_engine': 'lualatex'}) 697def test_polyglossia_with_language_de_1901(app, status, warning): 698 app.builder.build_all() 699 result = (app.outdir / 'python.tex').read_text() 700 print(result) 701 print(status.getvalue()) 702 print(warning.getvalue()) 703 assert '\\documentclass[letterpaper,10pt,german]{sphinxmanual}' in result 704 assert '\\usepackage{polyglossia}' in result 705 assert '\\setmainlanguage[spelling=old]{german}' in result 706 assert '\\usepackage{times}' not in result 707 assert '\\usepackage[Sonny]{fncychap}' in result 708 assert ('\\addto\\captionsgerman{\\renewcommand{\\contentsname}{Table of content}}\n' 709 in result) 710 assert '\\shorthandoff' not in result 711 712 # sphinxmessages.sty 713 result = (app.outdir / 'sphinxmessages.sty').read_text() 714 print(result) 715 assert r'\def\pageautorefname{page}' in result 716 assert r'\addto\captionsgerman{\renewcommand{\figurename}{Fig.\@{} }}' in result 717 assert r'\addto\captionsgerman{\renewcommand{\tablename}{Table.\@{} }}' in result 718 719 720@pytest.mark.sphinx('latex') 721def test_footnote(app, status, warning): 722 app.builder.build_all() 723 result = (app.outdir / 'sphinxtests.tex').read_text() 724 print(result) 725 print(status.getvalue()) 726 print(warning.getvalue()) 727 assert ('\\sphinxstepexplicit %\n\\begin{footnote}[1]\\phantomsection' 728 '\\label{\\thesphinxscope.1}%\n\\sphinxAtStartFootnote\nnumbered\n%\n' 729 '\\end{footnote}') in result 730 assert ('\\begin{footnote}[2]\\sphinxAtStartFootnote\nauto numbered\n%\n' 731 '\\end{footnote}') in result 732 assert '\\begin{footnote}[3]\\sphinxAtStartFootnote\nnamed\n%\n\\end{footnote}' in result 733 assert '\\sphinxcite{footnote:bar}' in result 734 assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result 735 assert '\\sphinxcaption{Table caption \\sphinxfootnotemark[4]' in result 736 assert ('\\hline%\n\\begin{footnotetext}[4]' 737 '\\phantomsection\\label{\\thesphinxscope.4}%\n' 738 '\\sphinxAtStartFootnote\n' 739 'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n' 740 '\\begin{footnotetext}[5]' 741 '\\phantomsection\\label{\\thesphinxscope.5}%\n' 742 '\\sphinxAtStartFootnote\n' 743 'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces ' 744 '\n\\sphinxAtStartPar\n' 745 'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result 746 assert ('Information about VIDIOC\\_CROPCAP %\n' 747 '\\begin{footnote}[6]\\sphinxAtStartFootnote\n' 748 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n\\hline\n' 749 '\\end{tabulary}\n' 750 '\\par\n\\sphinxattableend\\end{savenotes}\n') in result 751 752 753@pytest.mark.sphinx('latex', testroot='footnotes') 754def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning): 755 app.builder.build_all() 756 result = (app.outdir / 'python.tex').read_text() 757 print(result) 758 print(status.getvalue()) 759 print(warning.getvalue()) 760 assert ('\\caption{This is the figure caption with a reference to ' 761 '\\sphinxcite{index:authoryear}.}' in result) 762 assert '\\chapter{The section with a reference to {[}AuthorYear{]}}' in result 763 assert ('\\sphinxcaption{The table title with a reference' 764 ' to {[}AuthorYear{]}}' in result) 765 assert '\\subsubsection*{The rubric title with a reference to {[}AuthorYear{]}}' in result 766 assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n' 767 '\\label{\\detokenize{index:the-section-with-a-reference-to}}' 768 '%\n\\begin{footnotetext}[5]' 769 '\\phantomsection\\label{\\thesphinxscope.5}%\n' 770 '\\sphinxAtStartFootnote\n' 771 'Footnote in section\n%\n\\end{footnotetext}') in result 772 assert ('\\caption{This is the figure caption with a footnote to ' 773 '\\sphinxfootnotemark[7].}\\label{\\detokenize{index:id29}}\\end{figure}\n' 774 '%\n\\begin{footnotetext}[7]' 775 '\\phantomsection\\label{\\thesphinxscope.7}%\n' 776 '\\sphinxAtStartFootnote\n' 777 'Footnote in caption\n%\n\\end{footnotetext}') in result 778 assert ('\\sphinxcaption{footnote \\sphinxfootnotemark[8] in ' 779 'caption of normal table}\\label{\\detokenize{index:id30}}') in result 780 assert ('\\caption{footnote \\sphinxfootnotemark[9] ' 781 'in caption \\sphinxfootnotemark[10] of longtable\\strut}') in result 782 assert ('\\endlastfoot\n%\n\\begin{footnotetext}[9]' 783 '\\phantomsection\\label{\\thesphinxscope.9}%\n' 784 '\\sphinxAtStartFootnote\n' 785 'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n' 786 '\\begin{footnotetext}[10]' 787 '\\phantomsection\\label{\\thesphinxscope.10}%\n' 788 '\\sphinxAtStartFootnote\n' 789 'Second footnote in caption of longtable\n') in result 790 assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n' 791 '{\\hyperref[\\detokenize{index:codeblockinfootnote}]' 792 '{\\sphinxcrossref{\\DUrole{std,std-ref}{I am in a footnote}}}}') in result 793 assert ('&\n\\sphinxAtStartPar\nThis is one more footnote with some code in it %\n' 794 '\\begin{footnote}[11]\\sphinxAtStartFootnote\n' 795 'Third footnote in longtable\n') in result 796 assert ('\\end{sphinxVerbatim}\n%\n\\end{footnote}.\n') in result 797 assert '\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]' in result 798 799 800@pytest.mark.sphinx( 801 'latex', testroot='footnotes', 802 confoverrides={'latex_show_urls': 'inline'}) 803def test_latex_show_urls_is_inline(app, status, warning): 804 app.builder.build_all() 805 result = (app.outdir / 'python.tex').read_text() 806 print(result) 807 print(status.getvalue()) 808 print(warning.getvalue()) 809 assert ('Same footnote number \\sphinxstepexplicit %\n' 810 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 811 '\\sphinxAtStartFootnote\n' 812 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 813 assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' 814 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 815 assert ('\\phantomsection\\label{\\detokenize{index:id32}}' 816 '{\\hyperref[\\detokenize{index:the-section' 817 '-with-a-reference-to-authoryear}]' 818 '{\\sphinxcrossref{The section with a reference to ' 819 '\\sphinxcite{index:authoryear}}}}') in result 820 assert ('\\phantomsection\\label{\\detokenize{index:id33}}' 821 '{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]' 822 '{\\sphinxcrossref{The section with a reference to }}}' in result) 823 assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' 824 'First\n%\n\\end{footnote}') in result 825 assert ('Second footnote: \\sphinxstepexplicit %\n' 826 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 827 '\\sphinxAtStartFootnote\n' 828 'Second\n%\n\\end{footnote}') in result 829 assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result 830 assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' 831 'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n' 832 '\\begin{footnotetext}[4]' 833 '\\phantomsection\\label{\\thesphinxscope.4}%\n' 834 '\\sphinxAtStartFootnote\n' 835 'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result 836 assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} ' 837 '(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result 838 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} ' 839 '(http://sphinx\\sphinxhyphen{}doc.org/)}] ' 840 '\\leavevmode\n\\sphinxAtStartPar\nDescription' in result) 841 assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' 842 '\\leavevmode%\n\\begin{footnotetext}[6]' 843 '\\phantomsection\\label{\\thesphinxscope.6}%\n' 844 '\\sphinxAtStartFootnote\n' 845 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 846 '\n\\sphinxAtStartPar\nDescription') in result 847 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} ' 848 '(http://sphinx\\sphinxhyphen{}doc.org/)}] ' 849 '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result 850 assert '\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result 851 assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' 852 '{sphinx\\sphinxhyphen{}dev@googlegroups.com}') in result 853 assert '\\begin{savenotes}\\begin{fulllineitems}' not in result 854 855 856@pytest.mark.sphinx( 857 'latex', testroot='footnotes', 858 confoverrides={'latex_show_urls': 'footnote'}) 859def test_latex_show_urls_is_footnote(app, status, warning): 860 app.builder.build_all() 861 result = (app.outdir / 'python.tex').read_text() 862 print(result) 863 print(status.getvalue()) 864 print(warning.getvalue()) 865 assert ('Same footnote number \\sphinxstepexplicit %\n' 866 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 867 '\\sphinxAtStartFootnote\n' 868 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 869 assert ('Auto footnote number %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' 870 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 871 assert ('\\phantomsection\\label{\\detokenize{index:id32}}' 872 '{\\hyperref[\\detokenize{index:the-section-with-a-reference-to-authoryear}]' 873 '{\\sphinxcrossref{The section with a reference ' 874 'to \\sphinxcite{index:authoryear}}}}') in result 875 assert ('\\phantomsection\\label{\\detokenize{index:id33}}' 876 '{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]' 877 '{\\sphinxcrossref{The section with a reference to }}}') in result 878 assert ('First footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' 879 'First\n%\n\\end{footnote}') in result 880 assert ('Second footnote: \\sphinxstepexplicit %\n' 881 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 882 '\\sphinxAtStartFootnote\n' 883 'Second\n%\n\\end{footnote}') in result 884 assert ('\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' 885 '%\n\\begin{footnote}[4]\\sphinxAtStartFootnote\n' 886 '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result 887 assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n' 888 'Third \\sphinxfootnotemark[7]\n%\n\\end{footnote}%\n' 889 '\\begin{footnotetext}[7]' 890 '\\phantomsection\\label{\\thesphinxscope.7}%\n' 891 '\\sphinxAtStartFootnote\n' 892 'Footnote inside footnote\n%\n' 893 '\\end{footnotetext}\\ignorespaces') in result 894 assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' 895 '%\n\\begin{footnote}[5]\\sphinxAtStartFootnote\n' 896 '\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result 897 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}' 898 '{URL in term}\\sphinxfootnotemark[9]}] ' 899 '\\leavevmode%\n\\begin{footnotetext}[9]' 900 '\\phantomsection\\label{\\thesphinxscope.9}%\n' 901 '\\sphinxAtStartFootnote\n' 902 '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' 903 '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result 904 assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] ' 905 '\\leavevmode%\n\\begin{footnotetext}[11]' 906 '\\phantomsection\\label{\\thesphinxscope.11}%\n' 907 '\\sphinxAtStartFootnote\n' 908 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 909 '\n\\sphinxAtStartPar\nDescription') in result 910 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}' 911 '\\sphinxfootnotemark[10]}] ' 912 '\\leavevmode%\n\\begin{footnotetext}[10]' 913 '\\phantomsection\\label{\\thesphinxscope.10}%\n' 914 '\\sphinxAtStartFootnote\n' 915 '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' 916 '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result 917 assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result) 918 assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' 919 '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result 920 assert '\\begin{savenotes}\\begin{fulllineitems}' in result 921 922 923@pytest.mark.sphinx( 924 'latex', testroot='footnotes', 925 confoverrides={'latex_show_urls': 'no'}) 926def test_latex_show_urls_is_no(app, status, warning): 927 app.builder.build_all() 928 result = (app.outdir / 'python.tex').read_text() 929 print(result) 930 print(status.getvalue()) 931 print(warning.getvalue()) 932 assert ('Same footnote number \\sphinxstepexplicit %\n' 933 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 934 '\\sphinxAtStartFootnote\n' 935 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 936 assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' 937 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 938 assert ('\\phantomsection\\label{\\detokenize{index:id32}}' 939 '{\\hyperref[\\detokenize{index:the-section-with-a-reference-to-authoryear}]' 940 '{\\sphinxcrossref{The section with a reference ' 941 'to \\sphinxcite{index:authoryear}}}}') in result 942 assert ('\\phantomsection\\label{\\detokenize{index:id33}}' 943 '{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]' 944 '{\\sphinxcrossref{The section with a reference to }}}' in result) 945 assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' 946 'First\n%\n\\end{footnote}') in result 947 assert ('Second footnote: \\sphinxstepexplicit %\n' 948 '\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n' 949 '\\sphinxAtStartFootnote\n' 950 'Second\n%\n\\end{footnote}') in result 951 assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result 952 assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' 953 'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n' 954 '\\begin{footnotetext}[4]' 955 '\\phantomsection\\label{\\thesphinxscope.4}%\n' 956 '\\sphinxAtStartFootnote\n' 957 'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result 958 assert '\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' in result 959 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}] ' 960 '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result 961 assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' 962 '\\leavevmode%\n\\begin{footnotetext}[6]' 963 '\\phantomsection\\label{\\thesphinxscope.6}%\n' 964 '\\sphinxAtStartFootnote\n' 965 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 966 '\n\\sphinxAtStartPar\nDescription') in result 967 assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] ' 968 '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result 969 assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result) 970 assert ('\\sphinxhref{mailto:sphinx-dev@googlegroups.com}' 971 '{sphinx\\sphinxhyphen{}dev@googlegroups.com}\n') in result 972 assert '\\begin{savenotes}\\begin{fulllineitems}' not in result 973 974 975@pytest.mark.sphinx( 976 'latex', testroot='footnotes', 977 confoverrides={'latex_show_urls': 'footnote', 978 'rst_prolog': '.. |URL| replace:: `text <http://www.example.com/>`__'}) 979def test_latex_show_urls_footnote_and_substitutions(app, status, warning): 980 # hyperlinks in substitutions should not effect to make footnotes (refs: #4784) 981 test_latex_show_urls_is_footnote(app, status, warning) 982 983 984@pytest.mark.sphinx('latex', testroot='image-in-section') 985def test_image_in_section(app, status, warning): 986 app.builder.build_all() 987 result = (app.outdir / 'python.tex').read_text() 988 print(result) 989 print(status.getvalue()) 990 print(warning.getvalue()) 991 assert ('\\chapter[Test section]{\\lowercase{\\sphinxincludegraphics' 992 '[width=15bp,height=15bp]}{{pic}.png} Test section}' 993 in result) 994 assert ('\\chapter[Other {[}blah{]} section]{Other {[}blah{]} ' 995 '\\lowercase{\\sphinxincludegraphics[width=15bp,height=15bp]}' 996 '{{pic}.png} section}' in result) 997 assert ('\\chapter{Another section}' in result) 998 999 1000@pytest.mark.sphinx('latex', testroot='basic', 1001 confoverrides={'latex_logo': 'notfound.jpg'}) 1002def test_latex_logo_if_not_found(app, status, warning): 1003 try: 1004 app.builder.build_all() 1005 assert False # SphinxError not raised 1006 except Exception as exc: 1007 assert isinstance(exc, SphinxError) 1008 1009 1010@pytest.mark.sphinx('latex', testroot='toctree-maxdepth') 1011def test_toctree_maxdepth_manual(app, status, warning): 1012 app.builder.build_all() 1013 result = (app.outdir / 'python.tex').read_text() 1014 print(result) 1015 print(status.getvalue()) 1016 print(warning.getvalue()) 1017 assert '\\setcounter{tocdepth}{1}' in result 1018 assert '\\setcounter{secnumdepth}' not in result 1019 assert '\\chapter{Foo}' in result 1020 1021 1022@pytest.mark.sphinx( 1023 'latex', testroot='toctree-maxdepth', 1024 confoverrides={'latex_documents': [ 1025 ('index', 'python.tex', 'Sphinx Tests Documentation', 1026 'Georg Brandl', 'howto'), 1027 ]}) 1028def test_toctree_maxdepth_howto(app, status, warning): 1029 app.builder.build_all() 1030 result = (app.outdir / 'python.tex').read_text() 1031 print(result) 1032 print(status.getvalue()) 1033 print(warning.getvalue()) 1034 assert '\\setcounter{tocdepth}{2}' in result 1035 assert '\\setcounter{secnumdepth}' not in result 1036 assert '\\section{Foo}' in result 1037 1038 1039@pytest.mark.sphinx( 1040 'latex', testroot='toctree-maxdepth', 1041 confoverrides={'master_doc': 'foo'}) 1042def test_toctree_not_found(app, status, warning): 1043 app.builder.build_all() 1044 result = (app.outdir / 'python.tex').read_text() 1045 print(result) 1046 print(status.getvalue()) 1047 print(warning.getvalue()) 1048 assert '\\setcounter{tocdepth}' not in result 1049 assert '\\setcounter{secnumdepth}' not in result 1050 assert '\\chapter{Foo A}' in result 1051 1052 1053@pytest.mark.sphinx( 1054 'latex', testroot='toctree-maxdepth', 1055 confoverrides={'master_doc': 'bar'}) 1056def test_toctree_without_maxdepth(app, status, warning): 1057 app.builder.build_all() 1058 result = (app.outdir / 'python.tex').read_text() 1059 print(result) 1060 print(status.getvalue()) 1061 print(warning.getvalue()) 1062 assert '\\setcounter{tocdepth}' not in result 1063 assert '\\setcounter{secnumdepth}' not in result 1064 1065 1066@pytest.mark.sphinx( 1067 'latex', testroot='toctree-maxdepth', 1068 confoverrides={'master_doc': 'qux'}) 1069def test_toctree_with_deeper_maxdepth(app, status, warning): 1070 app.builder.build_all() 1071 result = (app.outdir / 'python.tex').read_text() 1072 print(result) 1073 print(status.getvalue()) 1074 print(warning.getvalue()) 1075 assert '\\setcounter{tocdepth}{3}' in result 1076 assert '\\setcounter{secnumdepth}{3}' in result 1077 1078 1079@pytest.mark.sphinx( 1080 'latex', testroot='toctree-maxdepth', 1081 confoverrides={'latex_toplevel_sectioning': None}) 1082def test_latex_toplevel_sectioning_is_None(app, status, warning): 1083 app.builder.build_all() 1084 result = (app.outdir / 'python.tex').read_text() 1085 print(result) 1086 print(status.getvalue()) 1087 print(warning.getvalue()) 1088 assert '\\chapter{Foo}' in result 1089 1090 1091@pytest.mark.sphinx( 1092 'latex', testroot='toctree-maxdepth', 1093 confoverrides={'latex_toplevel_sectioning': 'part'}) 1094def test_latex_toplevel_sectioning_is_part(app, status, warning): 1095 app.builder.build_all() 1096 result = (app.outdir / 'python.tex').read_text() 1097 print(result) 1098 print(status.getvalue()) 1099 print(warning.getvalue()) 1100 assert '\\part{Foo}' in result 1101 assert '\\chapter{Foo A}' in result 1102 assert '\\chapter{Foo B}' in result 1103 1104 1105@pytest.mark.sphinx( 1106 'latex', testroot='toctree-maxdepth', 1107 confoverrides={'latex_toplevel_sectioning': 'part', 1108 'latex_documents': [ 1109 ('index', 'python.tex', 'Sphinx Tests Documentation', 1110 'Georg Brandl', 'howto') 1111 ]}) 1112def test_latex_toplevel_sectioning_is_part_with_howto(app, status, warning): 1113 app.builder.build_all() 1114 result = (app.outdir / 'python.tex').read_text() 1115 print(result) 1116 print(status.getvalue()) 1117 print(warning.getvalue()) 1118 assert '\\part{Foo}' in result 1119 assert '\\section{Foo A}' in result 1120 assert '\\section{Foo B}' in result 1121 1122 1123@pytest.mark.sphinx( 1124 'latex', testroot='toctree-maxdepth', 1125 confoverrides={'latex_toplevel_sectioning': 'chapter'}) 1126def test_latex_toplevel_sectioning_is_chapter(app, status, warning): 1127 app.builder.build_all() 1128 result = (app.outdir / 'python.tex').read_text() 1129 print(result) 1130 print(status.getvalue()) 1131 print(warning.getvalue()) 1132 assert '\\chapter{Foo}' in result 1133 1134 1135@pytest.mark.sphinx( 1136 'latex', testroot='toctree-maxdepth', 1137 confoverrides={'latex_toplevel_sectioning': 'chapter', 1138 'latex_documents': [ 1139 ('index', 'python.tex', 'Sphinx Tests Documentation', 1140 'Georg Brandl', 'howto') 1141 ]}) 1142def test_latex_toplevel_sectioning_is_chapter_with_howto(app, status, warning): 1143 app.builder.build_all() 1144 result = (app.outdir / 'python.tex').read_text() 1145 print(result) 1146 print(status.getvalue()) 1147 print(warning.getvalue()) 1148 assert '\\section{Foo}' in result 1149 1150 1151@pytest.mark.sphinx( 1152 'latex', testroot='toctree-maxdepth', 1153 confoverrides={'latex_toplevel_sectioning': 'section'}) 1154def test_latex_toplevel_sectioning_is_section(app, status, warning): 1155 app.builder.build_all() 1156 result = (app.outdir / 'python.tex').read_text() 1157 print(result) 1158 print(status.getvalue()) 1159 print(warning.getvalue()) 1160 assert '\\section{Foo}' in result 1161 1162 1163@skip_if_stylefiles_notfound 1164@pytest.mark.sphinx('latex', testroot='maxlistdepth') 1165def test_maxlistdepth_at_ten(app, status, warning): 1166 app.builder.build_all() 1167 result = (app.outdir / 'python.tex').read_text() 1168 print(result) 1169 print(status.getvalue()) 1170 print(warning.getvalue()) 1171 compile_latex_document(app, 'python.tex') 1172 1173 1174@pytest.mark.skipif(docutils.__version_info__ < (0, 13), 1175 reason='docutils-0.13 or above is required') 1176@pytest.mark.sphinx('latex', testroot='latex-table') 1177@pytest.mark.test_params(shared_result='latex-table') 1178def test_latex_table_tabulars(app, status, warning): 1179 app.builder.build_all() 1180 result = (app.outdir / 'python.tex').read_text() 1181 tables = {} 1182 for chap in re.split(r'\\(?:section|chapter){', result)[1:]: 1183 sectname, content = chap.split('}', 1) 1184 tables[sectname] = content.strip() 1185 1186 def get_expected(name): 1187 return (app.srcdir / 'expects' / (name + '.tex')).read_text().strip() 1188 1189 # simple_table 1190 actual = tables['simple table'] 1191 expected = get_expected('simple_table') 1192 assert actual == expected 1193 1194 # table having :widths: option 1195 actual = tables['table having :widths: option'] 1196 expected = get_expected('table_having_widths') 1197 assert actual == expected 1198 1199 # table having :align: option (tabulary) 1200 actual = tables['table having :align: option (tabulary)'] 1201 expected = get_expected('tabulary_having_widths') 1202 assert actual == expected 1203 1204 # table having :align: option (tabular) 1205 actual = tables['table having :align: option (tabular)'] 1206 expected = get_expected('tabular_having_widths') 1207 assert actual == expected 1208 1209 # table with tabularcolumn 1210 actual = tables['table with tabularcolumn'] 1211 expected = get_expected('tabularcolumn') 1212 assert actual == expected 1213 1214 # table with cell in first column having three paragraphs 1215 actual = tables['table with cell in first column having three paragraphs'] 1216 expected = get_expected('table_having_threeparagraphs_cell_in_first_col') 1217 assert actual == expected 1218 1219 # table having caption 1220 actual = tables['table having caption'] 1221 expected = get_expected('table_having_caption') 1222 assert actual == expected 1223 1224 # table having verbatim 1225 actual = tables['table having verbatim'] 1226 expected = get_expected('table_having_verbatim') 1227 assert actual == expected 1228 1229 # table having problematic cell 1230 actual = tables['table having problematic cell'] 1231 expected = get_expected('table_having_problematic_cell') 1232 assert actual == expected 1233 1234 # table having both :widths: and problematic cell 1235 actual = tables['table having both :widths: and problematic cell'] 1236 expected = get_expected('table_having_widths_and_problematic_cell') 1237 assert actual == expected 1238 1239 # table having both stub columns and problematic cell 1240 actual = tables['table having both stub columns and problematic cell'] 1241 expected = get_expected('table_having_stub_columns_and_problematic_cell') 1242 assert actual == expected 1243 1244 1245@pytest.mark.skipif(docutils.__version_info__ < (0, 13), 1246 reason='docutils-0.13 or above is required') 1247@pytest.mark.sphinx('latex', testroot='latex-table') 1248@pytest.mark.test_params(shared_result='latex-table') 1249def test_latex_table_longtable(app, status, warning): 1250 app.builder.build_all() 1251 result = (app.outdir / 'python.tex').read_text() 1252 tables = {} 1253 for chap in re.split(r'\\(?:section|chapter){', result)[1:]: 1254 sectname, content = chap.split('}', 1) 1255 tables[sectname] = content.strip() 1256 1257 def get_expected(name): 1258 return (app.srcdir / 'expects' / (name + '.tex')).read_text().strip() 1259 1260 # longtable 1261 actual = tables['longtable'] 1262 expected = get_expected('longtable') 1263 assert actual == expected 1264 1265 # longtable having :widths: option 1266 actual = tables['longtable having :widths: option'] 1267 expected = get_expected('longtable_having_widths') 1268 assert actual == expected 1269 1270 # longtable having :align: option 1271 actual = tables['longtable having :align: option'] 1272 expected = get_expected('longtable_having_align') 1273 assert actual == expected 1274 1275 # longtable with tabularcolumn 1276 actual = tables['longtable with tabularcolumn'] 1277 expected = get_expected('longtable_with_tabularcolumn') 1278 assert actual == expected 1279 1280 # longtable having caption 1281 actual = tables['longtable having caption'] 1282 expected = get_expected('longtable_having_caption') 1283 assert actual == expected 1284 1285 # longtable having verbatim 1286 actual = tables['longtable having verbatim'] 1287 expected = get_expected('longtable_having_verbatim') 1288 assert actual == expected 1289 1290 # longtable having problematic cell 1291 actual = tables['longtable having problematic cell'] 1292 expected = get_expected('longtable_having_problematic_cell') 1293 assert actual == expected 1294 1295 # longtable having both :widths: and problematic cell 1296 actual = tables['longtable having both :widths: and problematic cell'] 1297 expected = get_expected('longtable_having_widths_and_problematic_cell') 1298 assert actual == expected 1299 1300 # longtable having both stub columns and problematic cell 1301 actual = tables['longtable having both stub columns and problematic cell'] 1302 expected = get_expected('longtable_having_stub_columns_and_problematic_cell') 1303 assert actual == expected 1304 1305 1306@pytest.mark.skipif(docutils.__version_info__ < (0, 13), 1307 reason='docutils-0.13 or above is required') 1308@pytest.mark.sphinx('latex', testroot='latex-table') 1309@pytest.mark.test_params(shared_result='latex-table') 1310def test_latex_table_complex_tables(app, status, warning): 1311 app.builder.build_all() 1312 result = (app.outdir / 'python.tex').read_text() 1313 tables = {} 1314 for chap in re.split(r'\\(?:section|renewcommand){', result)[1:]: 1315 sectname, content = chap.split('}', 1) 1316 tables[sectname] = content.strip() 1317 1318 def get_expected(name): 1319 return (app.srcdir / 'expects' / (name + '.tex')).read_text().strip() 1320 1321 # grid table 1322 actual = tables['grid table'] 1323 expected = get_expected('gridtable') 1324 assert actual == expected 1325 1326 # complex spanning cell 1327 actual = tables['complex spanning cell'] 1328 expected = get_expected('complex_spanning_cell') 1329 assert actual == expected 1330 1331 1332@pytest.mark.sphinx('latex', testroot='latex-table', 1333 confoverrides={'templates_path': ['_mytemplates/latex']}) 1334def test_latex_table_custom_template_caseA(app, status, warning): 1335 app.builder.build_all() 1336 result = (app.outdir / 'python.tex').read_text() 1337 assert 'SALUT LES COPAINS' in result 1338 1339 1340@pytest.mark.sphinx('latex', testroot='latex-table', 1341 confoverrides={'templates_path': ['_mytemplates']}) 1342def test_latex_table_custom_template_caseB(app, status, warning): 1343 app.builder.build_all() 1344 result = (app.outdir / 'python.tex').read_text() 1345 assert 'SALUT LES COPAINS' not in result 1346 1347 1348@pytest.mark.sphinx('latex', testroot='latex-table') 1349@pytest.mark.test_params(shared_result='latex-table') 1350def test_latex_table_custom_template_caseC(app, status, warning): 1351 app.builder.build_all() 1352 result = (app.outdir / 'python.tex').read_text() 1353 assert 'SALUT LES COPAINS' not in result 1354 1355 1356@pytest.mark.sphinx('latex', testroot='directives-raw') 1357def test_latex_raw_directive(app, status, warning): 1358 app.builder.build_all() 1359 result = (app.outdir / 'python.tex').read_text() 1360 1361 # standard case 1362 assert 'standalone raw directive (HTML)' not in result 1363 assert ('\\label{\\detokenize{index:id1}}\n' 1364 'standalone raw directive (LaTeX)' in result) 1365 1366 # with substitution 1367 assert 'HTML: abc ghi' in result 1368 assert 'LaTeX: abc def ghi' in result 1369 1370 1371@pytest.mark.sphinx('latex', testroot='images') 1372def test_latex_images(app, status, warning): 1373 app.builder.build_all() 1374 1375 result = (app.outdir / 'python.tex').read_text() 1376 1377 # images are copied 1378 assert '\\sphinxincludegraphics{{python-logo}.png}' in result 1379 assert (app.outdir / 'python-logo.png').exists() 1380 1381 # not found images 1382 assert '\\sphinxincludegraphics{{NOT_EXIST}.PNG}' not in result 1383 assert ('WARNING: Could not fetch remote image: ' 1384 'https://www.google.com/NOT_EXIST.PNG [404]' in warning.getvalue()) 1385 1386 # an image having target 1387 assert ('\\sphinxhref{https://www.sphinx-doc.org/}' 1388 '{\\sphinxincludegraphics{{rimg}.png}}\n\n' in result) 1389 1390 # a centerized image having target 1391 assert ('\\sphinxhref{https://www.python.org/}{{\\hspace*{\\fill}' 1392 '\\sphinxincludegraphics{{rimg}.png}\\hspace*{\\fill}}}\n\n' in result) 1393 1394 1395@pytest.mark.sphinx('latex', testroot='latex-index') 1396def test_latex_index(app, status, warning): 1397 app.builder.build_all() 1398 1399 result = (app.outdir / 'python.tex').read_text() 1400 assert ('A \\index{famous@\\spxentry{famous}}famous ' 1401 '\\index{equation@\\spxentry{equation}}equation:\n' in result) 1402 assert ('\n\\index{Einstein@\\spxentry{Einstein}}' 1403 '\\index{relativity@\\spxentry{relativity}}' 1404 '\\ignorespaces \n\\sphinxAtStartPar\nand') in result 1405 assert ('\n\\index{main \\sphinxleftcurlybrace{}@\\spxentry{' 1406 'main \\sphinxleftcurlybrace{}}}\\ignorespaces ' in result) 1407 1408 1409@pytest.mark.sphinx('latex', testroot='latex-equations') 1410def test_latex_equations(app, status, warning): 1411 app.builder.build_all() 1412 1413 result = (app.outdir / 'python.tex').read_text() 1414 expected = (app.srcdir / 'expects' / 'latex-equations.tex').read_text().strip() 1415 1416 assert expected in result 1417 1418 1419@pytest.mark.sphinx('latex', testroot='image-in-parsed-literal') 1420def test_latex_image_in_parsed_literal(app, status, warning): 1421 app.builder.build_all() 1422 1423 result = (app.outdir / 'python.tex').read_text() 1424 assert ('{\\sphinxunactivateextrasandspace \\raisebox{-0.5\\height}' 1425 '{\\sphinxincludegraphics[height=2.00000cm]{{pic}.png}}' 1426 '}AFTER') in result 1427 1428 1429@pytest.mark.sphinx('latex', testroot='nested-enumerated-list') 1430def test_latex_nested_enumerated_list(app, status, warning): 1431 app.builder.build_all() 1432 1433 result = (app.outdir / 'python.tex').read_text() 1434 assert ('\\sphinxsetlistlabels{\\arabic}{enumi}{enumii}{}{.}%\n' 1435 '\\setcounter{enumi}{4}\n' in result) 1436 assert ('\\sphinxsetlistlabels{\\alph}{enumii}{enumiii}{}{.}%\n' 1437 '\\setcounter{enumii}{3}\n' in result) 1438 assert ('\\sphinxsetlistlabels{\\arabic}{enumiii}{enumiv}{}{)}%\n' 1439 '\\setcounter{enumiii}{9}\n' in result) 1440 assert ('\\sphinxsetlistlabels{\\arabic}{enumiv}{enumv}{(}{)}%\n' 1441 '\\setcounter{enumiv}{23}\n' in result) 1442 assert ('\\sphinxsetlistlabels{\\roman}{enumii}{enumiii}{}{.}%\n' 1443 '\\setcounter{enumii}{2}\n' in result) 1444 1445 1446@pytest.mark.sphinx('latex', testroot='footnotes') 1447def test_latex_thebibliography(app, status, warning): 1448 app.builder.build_all() 1449 1450 result = (app.outdir / 'python.tex').read_text() 1451 print(result) 1452 assert ('\\begin{sphinxthebibliography}{AuthorYe}\n' 1453 '\\bibitem[AuthorYear]{index:authoryear}\n\\sphinxAtStartPar\n' 1454 'Author, Title, Year\n' 1455 '\\end{sphinxthebibliography}\n' in result) 1456 assert '\\sphinxcite{index:authoryear}' in result 1457 1458 1459@pytest.mark.sphinx('latex', testroot='glossary') 1460def test_latex_glossary(app, status, warning): 1461 app.builder.build_all() 1462 1463 result = (app.outdir / 'python.tex').read_text() 1464 assert ('\\item[{änhlich\\index{änhlich@\\spxentry{änhlich}|spxpagem}' 1465 r'\phantomsection' 1466 r'\label{\detokenize{index:term-anhlich}}}] \leavevmode' in result) 1467 assert (r'\item[{boson\index{boson@\spxentry{boson}|spxpagem}\phantomsection' 1468 r'\label{\detokenize{index:term-boson}}}] \leavevmode' in result) 1469 assert (r'\item[{\sphinxstyleemphasis{fermion}' 1470 r'\index{fermion@\spxentry{fermion}|spxpagem}' 1471 r'\phantomsection' 1472 r'\label{\detokenize{index:term-fermion}}}] \leavevmode' in result) 1473 assert (r'\item[{tauon\index{tauon@\spxentry{tauon}|spxpagem}\phantomsection' 1474 r'\label{\detokenize{index:term-tauon}}}] \leavevmode' 1475 r'\item[{myon\index{myon@\spxentry{myon}|spxpagem}\phantomsection' 1476 r'\label{\detokenize{index:term-myon}}}] \leavevmode' 1477 r'\item[{electron\index{electron@\spxentry{electron}|spxpagem}\phantomsection' 1478 r'\label{\detokenize{index:term-electron}}}] \leavevmode' in result) 1479 assert ('\\item[{über\\index{über@\\spxentry{über}|spxpagem}\\phantomsection' 1480 r'\label{\detokenize{index:term-uber}}}] \leavevmode' in result) 1481 1482 1483@pytest.mark.sphinx('latex', testroot='latex-labels') 1484def test_latex_labels(app, status, warning): 1485 app.builder.build_all() 1486 1487 result = (app.outdir / 'python.tex').read_text() 1488 1489 # figures 1490 assert (r'\caption{labeled figure}' 1491 r'\label{\detokenize{index:id1}}' 1492 r'\label{\detokenize{index:figure2}}' 1493 r'\label{\detokenize{index:figure1}}' 1494 r'\end{figure}' in result) 1495 assert (r'\caption{labeled figure}' 1496 '\\label{\\detokenize{index:figure3}}\n' 1497 '\\begin{sphinxlegend}\n\\sphinxAtStartPar\n' 1498 'with a legend\n\\end{sphinxlegend}\n' 1499 r'\end{figure}' in result) 1500 1501 # code-blocks 1502 assert (r'\def\sphinxLiteralBlockLabel{' 1503 r'\label{\detokenize{index:codeblock2}}' 1504 r'\label{\detokenize{index:codeblock1}}}' in result) 1505 assert (r'\def\sphinxLiteralBlockLabel{' 1506 r'\label{\detokenize{index:codeblock3}}}' in result) 1507 1508 # tables 1509 assert (r'\sphinxcaption{table caption}' 1510 r'\label{\detokenize{index:id2}}' 1511 r'\label{\detokenize{index:table2}}' 1512 r'\label{\detokenize{index:table1}}' in result) 1513 assert (r'\sphinxcaption{table caption}' 1514 r'\label{\detokenize{index:table3}}' in result) 1515 1516 # sections 1517 assert ('\\chapter{subsection}\n' 1518 r'\label{\detokenize{index:subsection}}' 1519 r'\label{\detokenize{index:section2}}' 1520 r'\label{\detokenize{index:section1}}' in result) 1521 assert ('\\section{subsubsection}\n' 1522 r'\label{\detokenize{index:subsubsection}}' 1523 r'\label{\detokenize{index:section3}}' in result) 1524 assert ('\\subsection{otherdoc}\n' 1525 r'\label{\detokenize{otherdoc:otherdoc}}' 1526 r'\label{\detokenize{otherdoc::doc}}' in result) 1527 1528 # Embedded standalone hyperlink reference (refs: #5948) 1529 assert result.count(r'\label{\detokenize{index:section1}}') == 1 1530 1531 1532@pytest.mark.sphinx('latex', testroot='latex-figure-in-admonition') 1533def test_latex_figure_in_admonition(app, status, warning): 1534 app.builder.build_all() 1535 result = (app.outdir / 'python.tex').read_text() 1536 assert(r'\begin{figure}[H]' in result) 1537 1538 1539def test_default_latex_documents(): 1540 from sphinx.util import texescape 1541 texescape.init() 1542 config = Config({'master_doc': 'index', 1543 'project': 'STASI™ Documentation', 1544 'author': "Wolfgang Schäuble & G'Beckstein."}) 1545 config.init_values() 1546 config.add('latex_engine', None, True, None) 1547 config.add('latex_theme', 'manual', True, None) 1548 expected = [('index', 'stasi.tex', 'STASI™ Documentation', 1549 r"Wolfgang Schäuble \& G\textquotesingle{}Beckstein.\@{}", 'manual')] 1550 assert default_latex_documents(config) == expected 1551 1552 1553@skip_if_requested 1554@skip_if_stylefiles_notfound 1555@pytest.mark.sphinx('latex', testroot='latex-includegraphics') 1556def test_includegraphics_oversized(app, status, warning): 1557 app.builder.build_all() 1558 print(status.getvalue()) 1559 print(warning.getvalue()) 1560 compile_latex_document(app) 1561 1562 1563@pytest.mark.sphinx('latex', testroot='index_on_title') 1564def test_index_on_title(app, status, warning): 1565 app.builder.build_all() 1566 result = (app.outdir / 'python.tex').read_text() 1567 assert ('\\chapter{Test for index in top level title}\n' 1568 '\\label{\\detokenize{contents:test-for-index-in-top-level-title}}' 1569 '\\index{index@\\spxentry{index}}\n' 1570 in result) 1571 1572 1573@pytest.mark.sphinx('latex', testroot='latex-unicode', 1574 confoverrides={'latex_engine': 'pdflatex'}) 1575def test_texescape_for_non_unicode_supported_engine(app, status, warning): 1576 app.builder.build_all() 1577 result = (app.outdir / 'python.tex').read_text() 1578 print(result) 1579 assert 'script small e: e' in result 1580 assert 'double struck italic small i: i' in result 1581 assert r'superscript: \(\sp{\text{0}}\), \(\sp{\text{1}}\)' in result 1582 assert r'subscript: \(\sb{\text{0}}\), \(\sb{\text{1}}\)' in result 1583 1584 1585@pytest.mark.sphinx('latex', testroot='latex-unicode', 1586 confoverrides={'latex_engine': 'xelatex'}) 1587def test_texescape_for_unicode_supported_engine(app, status, warning): 1588 app.builder.build_all() 1589 result = (app.outdir / 'python.tex').read_text() 1590 print(result) 1591 assert 'script small e: e' in result 1592 assert 'double struck italic small i: i' in result 1593 assert 'superscript: ⁰, ¹' in result 1594 assert 'subscript: ₀, ₁' in result 1595 1596 1597@pytest.mark.sphinx('latex', testroot='basic', 1598 confoverrides={'latex_elements': {'extrapackages': r'\usepackage{foo}'}}) 1599def test_latex_elements_extrapackages(app, status, warning): 1600 app.builder.build_all() 1601 result = (app.outdir / 'test.tex').read_text() 1602 assert r'\usepackage{foo}' in result 1603 1604 1605@pytest.mark.sphinx('latex', testroot='nested-tables') 1606def test_latex_nested_tables(app, status, warning): 1607 app.builder.build_all() 1608 assert '' == warning.getvalue() 1609