git.iko.soy/typeable/pandoc
on master help sign in
LaTeX writer: always add hypertarget when there's a non-empty identifier.

Previously the hypertargets were only added when there was actually a link to that identifier. Closes #2719.

commitfe4311d5a1482ab2e0edfe78c556bf28fc50adf7 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 1 Mar 2017, 21:38 (10 years ago) parentd21c7fe
6 files changed+94−67
src/Text/Pandoc/Writers/LaTeX.hs+19−29 test/Tests/Writers/LaTeX.hs+1−1 test/lhs-test.latex+2−1 test/lhs-test.latex+lhs+2−1 test/writer.latex+62−31 test/writers-lang-and-dir.latex+8−4
src/Text/Pandoc/Writers/LaTeX.hs+19−29
@@ -418,11 +418,7 @@ blockToLaTeX :: PandocMonad m
418418blockToLaTeX Null = return empty
419419blockToLaTeX (Div (identifier,classes,kvs) bs) = do
420420 beamer <- gets stBeamer
421− ref <- toLabel identifier
422− let linkAnchor = if null identifier
423− then empty
424− else "\\hypertarget" <> braces (text ref) <>
425− braces empty
421+ linkAnchor <- hypertarget True identifier empty
426422 let align dir txt = inCmd "begin" dir $$ txt $$ inCmd "end" dir
427423 let wrapDir = case lookup "dir" kvs of
428424 Just "rtl" -> align "RTL"
@@ -459,13 +455,13 @@ blockToLaTeX (Para [Image attr@(ident, _, _) txt (src,'f':'i':'g':':':tit)]) = d
459455 let footnotes = notesToLaTeX notes
460456 lab <- labelFor ident
461457 let caption = "\\caption" <> captForLof <> braces capt <> lab
462− figure <- hypertarget ident (cr <>
463− "\\begin{figure}" $$ "\\centering" $$ img $$
464− caption $$ "\\end{figure}" <> cr)
458+ let figure = cr <> "\\begin{figure}" $$ "\\centering" $$ img $$
459+ caption $$ "\\end{figure}" <> cr
460+ figure' <- hypertarget True ident figure
465461 return $ if inNote
466462 -- can't have figures in notes
467463 then "\\begin{center}" $$ img $+$ capt $$ "\\end{center}"
468− else figure $$ footnotes
464+ else figure' $$ footnotes
469465-- . . . indicates pause in beamer slides
470466blockToLaTeX (Para [Str ".",Space,Str ".",Space,Str "."]) = do
471467 beamer <- gets stBeamer
@@ -493,11 +489,8 @@ blockToLaTeX (BlockQuote lst) = do
493489 return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"
494490blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do
495491 opts <- gets stOptions
496− ref <- toLabel identifier
497− let linkAnchor = if null identifier
498− then empty
499− else "\\hypertarget" <> braces (text ref) <>
500− braces ("\\label" <> braces (text ref))
492+ lab <- labelFor identifier
493+ linkAnchor <- hypertarget True identifier lab
501494 let lhsCodeBlock = do
502495 modify $ \s -> s{ stLHS = True }
503496 return $ flush (linkAnchor $$ "\\begin{code}" $$ text str $$
@@ -512,6 +505,7 @@ blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do
512505 text str $$ text ("\\end{" ++ env ++ "}")) <> cr
513506 let listingsCodeBlock = do
514507 st <- get
508+ ref <- toLabel identifier
515509 let params = if writerListings (stOptions st)
516510 then (case getListingsLanguage classes of
517511 Just l -> [ "language=" ++ mbBraced l ]
@@ -830,7 +824,8 @@ sectionHeader unnumbered ident level lst = do
830824 lab <- labelFor ident
831825 let star = if unnumbered && level' < 4 then text "*" else empty
832826 let stuffing = star <> optional <> contents
833− stuffing' <- hypertarget ident $ text ('\\':sectionType) <> stuffing <> lab
827+ stuffing' <- hypertarget True ident $
828+ text ('\\':sectionType) <> stuffing <> lab
834829 return $ if level' > 5
835830 then txt
836831 else prefix $$ stuffing'
@@ -840,16 +835,13 @@ sectionHeader unnumbered ident level lst = do
840835 braces txtNoNotes
841836 else empty
842837
843−hypertarget :: PandocMonad m => String -> Doc -> LW m Doc
844−hypertarget ident x = do
838+hypertarget :: PandocMonad m => Bool -> String -> Doc -> LW m Doc
839+hypertarget _ "" x = return x
840+hypertarget addnewline ident x = do
845841 ref <- text `fmap` toLabel ident
846− internalLinks <- gets stInternalLinks
847− return $
848− if ident `elem` internalLinks
849− then text "\\hypertarget"
842+ return $ text "\\hypertarget"
850843 <> braces ref
851− <> braces x
852− else x
844+ <> braces ((if addnewline then ("%" <> cr) else empty) <> x)
853845
854846labelFor :: PandocMonad m => String -> LW m Doc
855847labelFor "" = return empty
@@ -892,11 +884,7 @@ inlineToLaTeX :: PandocMonad m
892884 => Inline -- ^ Inline to convert
893885 -> LW m Doc
894886inlineToLaTeX (Span (id',classes,kvs) ils) = do
895− ref <- toLabel id'
896− let linkAnchor = if null id'
897− then empty
898− else "\\protect\\hypertarget" <> braces (text ref) <>
899− braces empty
887+ linkAnchor <- hypertarget False id' empty
900888 let cmds = ["textup" | "csl-no-emph" `elem` classes] ++
901889 ["textnormal" | "csl-no-strong" `elem` classes ||
902890 "csl-no-smallcaps" `elem` classes] ++
@@ -908,7 +896,9 @@ inlineToLaTeX (Span (id',classes,kvs) ils) = do
908896 in ["text" ++ l ++ ops]
909897 Nothing -> [])
910898 contents <- inlineListToLaTeX ils
911− return $ linkAnchor <>
899+ return $ (if null id'
900+ then empty
901+ else "\\protect" <> linkAnchor) <>
912902 if null cmds
913903 then braces contents
914904 else foldr inCmd contents cmds
test/Tests/Writers/LaTeX.hs+1−1
@@ -58,7 +58,7 @@ tests = [ testGroup "code blocks"
5858 [ "unnumbered header" =:
5959 headerWith ("foo",["unnumbered"],[]) 1
6060 (text "Header 1" <> note (plain $ text "note")) =?>
61− "\\section*{\\texorpdfstring{Header 1\\footnote{note}}{Header 1}}\\label{foo}\n\\addcontentsline{toc}{section}{Header 1}\n"
61+ "\\hypertarget{foo}{%\n\\section*{\\texorpdfstring{Header 1\\footnote{note}}{Header 1}}\\label{foo}}\n\\addcontentsline{toc}{section}{Header 1}\n"
6262 , "in list item" =:
6363 bulletList [header 2 (text "foo")] =?>
6464 "\\begin{itemize}\n\\item ~\n \\subsection{foo}\n\\end{itemize}"
test/lhs-test.latex+2−1
@@ -91,7 +91,8 @@
9191
9292\begin{document}
9393
94−\section{lhs test}\label{lhs-test}
94+\hypertarget{lhs-test}{%
95+\section{lhs test}\label{lhs-test}}
9596
9697\texttt{unsplit} is an arrow that takes a pair of values and combines them to
9798return a single value:
test/lhs-test.latex+lhs+2−1
@@ -55,7 +55,8 @@
5555
5656\begin{document}
5757
58−\section{lhs test}\label{lhs-test}
58+\hypertarget{lhs-test}{%
59+\section{lhs test}\label{lhs-test}}
5960
6061\texttt{unsplit} is an arrow that takes a pair of values and combines them to
6162return a single value:
test/writer.latex+62−31
@@ -77,34 +77,44 @@ markdown test suite.
7777
7878\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
7979
80−\section{Headers}\label{headers}
80+\hypertarget{headers}{%
81+\section{Headers}\label{headers}}
8182
83+\hypertarget{level-2-with-an-embedded-link}{%
8284\subsection{\texorpdfstring{Level 2 with an \href{/url}{embedded
83−link}}{Level 2 with an embedded link}}\label{level-2-with-an-embedded-link}
85+link}}{Level 2 with an embedded link}}\label{level-2-with-an-embedded-link}}
8486
87+\hypertarget{level-3-with-emphasis}{%
8588\subsubsection{\texorpdfstring{Level 3 with
86−\emph{emphasis}}{Level 3 with emphasis}}\label{level-3-with-emphasis}
89+\emph{emphasis}}{Level 3 with emphasis}}\label{level-3-with-emphasis}}
8790
88−\paragraph{Level 4}\label{level-4}
91+\hypertarget{level-4}{%
92+\paragraph{Level 4}\label{level-4}}
8993
90−\subparagraph{Level 5}\label{level-5}
94+\hypertarget{level-5}{%
95+\subparagraph{Level 5}\label{level-5}}
9196
92−\section{Level 1}\label{level-1}
97+\hypertarget{level-1}{%
98+\section{Level 1}\label{level-1}}
9399
100+\hypertarget{level-2-with-emphasis}{%
94101\subsection{\texorpdfstring{Level 2 with
95−\emph{emphasis}}{Level 2 with emphasis}}\label{level-2-with-emphasis}
102+\emph{emphasis}}{Level 2 with emphasis}}\label{level-2-with-emphasis}}
96103
97−\subsubsection{Level 3}\label{level-3}
104+\hypertarget{level-3}{%
105+\subsubsection{Level 3}\label{level-3}}
98106
99107with no blank line
100108
101−\subsection{Level 2}\label{level-2}
109+\hypertarget{level-2}{%
110+\subsection{Level 2}\label{level-2}}
102111
103112with no blank line
104113
105114\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
106115
107−\section{Paragraphs}\label{paragraphs}
116+\hypertarget{paragraphs}{%
117+\section{Paragraphs}\label{paragraphs}}
108118
109119Here's a regular paragraph.
110120
@@ -119,7 +129,8 @@ here.
119129
120130\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
121131
122−\section{Block Quotes}\label{block-quotes}
132+\hypertarget{block-quotes}{%
133+\section{Block Quotes}\label{block-quotes}}
123134
124135E-mail style:
125136
@@ -164,7 +175,8 @@ And a following paragraph.
164175
165176\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
166177
167−\section{Code Blocks}\label{code-blocks}
178+\hypertarget{code-blocks}{%
179+\section{Code Blocks}\label{code-blocks}}
168180
169181Code:
170182
@@ -188,9 +200,11 @@ These should not be escaped: \$ \\ \> \[ \{
188200
189201\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
190202
191−\section{Lists}\label{lists}
203+\hypertarget{lists}{%
204+\section{Lists}\label{lists}}
192205
193−\subsection{Unordered}\label{unordered}
206+\hypertarget{unordered}{%
207+\subsection{Unordered}\label{unordered}}
194208
195209Asterisks tight:
196210
@@ -261,7 +275,8 @@ Minuses loose:
261275 Minus 3
262276\end{itemize}
263277
264−\subsection{Ordered}\label{ordered}
278+\hypertarget{ordered}{%
279+\subsection{Ordered}\label{ordered}}
265280
266281Tight:
267282
@@ -327,7 +342,8 @@ Multiple paragraphs:
327342 Item 3.
328343\end{enumerate}
329344
330−\subsection{Nested}\label{nested}
345+\hypertarget{nested}{%
346+\subsection{Nested}\label{nested}}
331347
332348\begin{itemize}
333349\tightlist
@@ -392,7 +408,8 @@ Same thing but with paragraphs:
392408 Third
393409\end{enumerate}
394410
395−\subsection{Tabs and spaces}\label{tabs-and-spaces}
411+\hypertarget{tabs-and-spaces}{%
412+\subsection{Tabs and spaces}\label{tabs-and-spaces}}
396413
397414\begin{itemize}
398415\item
@@ -408,7 +425,8 @@ Same thing but with paragraphs:
408425 \end{itemize}
409426\end{itemize}
410427
411−\subsection{Fancy list markers}\label{fancy-list-markers}
428+\hypertarget{fancy-list-markers}{%
429+\subsection{Fancy list markers}\label{fancy-list-markers}}
412430
413431\begin{enumerate}
414432\def\labelenumi{(\arabic{enumi})}
@@ -496,7 +514,8 @@ B. Williams
496514
497515\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
498516
499−\section{Definition Lists}\label{definition-lists}
517+\hypertarget{definition-lists}{%
518+\section{Definition Lists}\label{definition-lists}}
500519
501520Tight using spaces:
502521
@@ -599,7 +618,8 @@ orange fruit
599618\end{enumerate}
600619\end{description}
601620
602−\section{HTML Blocks}\label{html-blocks}
621+\hypertarget{html-blocks}{%
622+\section{HTML Blocks}\label{html-blocks}}
603623
604624Simple block on one line:
605625
@@ -661,7 +681,8 @@ Hr's:
661681
662682\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
663683
664−\section{Inline Markup}\label{inline-markup}
684+\hypertarget{inline-markup}{%
685+\section{Inline Markup}\label{inline-markup}}
665686
666687This is \emph{emphasized}, and so \emph{is this}.
667688
@@ -693,7 +714,8 @@ spaces: a\^{}b c\^{}d, a\textasciitilde{}b c\textasciitilde{}d.
693714
694715\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
695716
696−\section{Smart quotes, ellipses, dashes}\label{smart-quotes-ellipses-dashes}
717+\hypertarget{smart-quotes-ellipses-dashes}{%
718+\section{Smart quotes, ellipses, dashes}\label{smart-quotes-ellipses-dashes}}
697719
698720``Hello,'' said the spider. ``\,`Shelob' is my name.''
699721
@@ -714,7 +736,8 @@ Ellipses\ldots{}and\ldots{}and\ldots{}.
714736
715737\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
716738
717−\section{LaTeX}\label{latex}
739+\hypertarget{latex}{%
740+\section{LaTeX}\label{latex}}
718741
719742\begin{itemize}
720743\tightlist
@@ -762,7 +785,8 @@ Cat & 1 \\ \hline
762785
763786\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
764787
765−\section{Special Characters}\label{special-characters}
788+\hypertarget{special-characters}{%
789+\section{Special Characters}\label{special-characters}}
766790
767791Here is some unicode:
768792
@@ -824,9 +848,11 @@ Minus: -
824848
825849\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
826850
827−\section{Links}\label{links}
851+\hypertarget{links}{%
852+\section{Links}\label{links}}
828853
829−\subsection{Explicit}\label{explicit}
854+\hypertarget{explicit}{%
855+\subsection{Explicit}\label{explicit}}
830856
831857Just a \href{/url/}{URL}.
832858
@@ -846,7 +872,8 @@ Just a \href{/url/}{URL}.
846872
847873\href{}{Empty}.
848874
849−\subsection{Reference}\label{reference}
875+\hypertarget{reference}{%
876+\subsection{Reference}\label{reference}}
850877
851878Foo \href{/url/}{bar}.
852879
@@ -874,7 +901,8 @@ Foo \href{/url/}{bar}.
874901
875902Foo \href{/url/}{biz}.
876903
877−\subsection{With ampersands}\label{with-ampersands}
904+\hypertarget{with-ampersands}{%
905+\subsection{With ampersands}\label{with-ampersands}}
878906
879907Here's a \href{http://example.com/?foo=1\&bar=2}{link with an ampersand in the
880908URL}.
@@ -886,7 +914,8 @@ Here's an \href{/script?foo=1\&bar=2}{inline link}.
886914
887915Here's an \href{/script?foo=1\&bar=2}{inline link in pointy braces}.
888916
889−\subsection{Autolinks}\label{autolinks}
917+\hypertarget{autolinks}{%
918+\subsection{Autolinks}\label{autolinks}}
890919
891920With an ampersand: \url{http://example.com/?foo=1\&bar=2}
892921
@@ -916,7 +945,8 @@ or here: <http://example.com/>
916945
917946\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
918947
919−\section{Images}\label{images}
948+\hypertarget{images}{%
949+\section{Images}\label{images}}
920950
921951From ``Voyage dans la Lune'' by Georges Melies (1902):
922952
@@ -930,7 +960,8 @@ Here is a movie \includegraphics{movie.jpg} icon.
930960
931961\begin{center}\rule{0.5\linewidth}{\linethickness}\end{center}
932962
933−\section{Footnotes}\label{footnotes}
963+\hypertarget{footnotes}{%
964+\section{Footnotes}\label{footnotes}}
934965
935966Here is a footnote reference,\footnote{Here is the footnote. It can go
936967 anywhere after the footnote reference. It need not be placed at the end of
test/writers-lang-and-dir.latex+8−4
@@ -84,7 +84,8 @@
8484
8585\begin{document}
8686
87−\section{Empty Divs and Spans}\label{empty-divs-and-spans}
87+\hypertarget{empty-divs-and-spans}{%
88+\section{Empty Divs and Spans}\label{empty-divs-and-spans}}
8889
8990Some text and
9091
@@ -94,7 +95,8 @@ and more text.
9495
9596Next paragraph with a {span} and a word-thatincludesa{span}right?
9697
97−\section{Directionality}\label{directionality}
98+\hypertarget{directionality}{%
99+\section{Directionality}\label{directionality}}
98100
99101Some text and
100102
@@ -111,7 +113,8 @@ and a ltr div. with a \RL{rtl span}.
111113Next paragraph with a \RL{rtl span} and a
112114word-that-includesa\LR{ltrspan}right?
113115
114−\section{Languages}\label{languages}
116+\hypertarget{languages}{%
117+\section{Languages}\label{languages}}
115118
116119Some text and
117120
@@ -128,7 +131,8 @@ word-that-includesa\textgerman[variant=swiss]{Swiss German span}right?
128131
129132Some \textspanish{Spanish text}.
130133
131−\section{Combined}\label{combined}
134+\hypertarget{combined}{%
135+\section{Combined}\label{combined}}
132136
133137Some text and
134138