Skip to content

Commit

Permalink
Render citations links as arbitrary markdown AST
Browse files Browse the repository at this point in the history
Change `format_citation` so that is returns markdown code that replaces
the entire original link.

* Enable multiple citation in a single cite link, which can be collapsed
  in the default `:numeric` style
* Support citation keys with underscores
* Handle in-line formatting in "citation notes"
* Handle missing references in non-strict mode by printing question
  marks (just like LaTeX)

Substantial restructuring of internals
  • Loading branch information
goerz committed Oct 12, 2023
1 parent bd50797 commit 06a54f7
Show file tree
Hide file tree
Showing 48 changed files with 1,983 additions and 1,166 deletions.
16 changes: 16 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
coverage:
precision: 1
range:
- 70.0
- 90.0
round: up
status:
patch:
default:
informational: true
target: 90.0
project:
default:
informational: true
target: auto
threshold: 3.0
29 changes: 29 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased][]

### Fixed

* Skip the expansion of citations and bibliographies when running in doctest mode [[#34][]]
* Support underscores in citation keys [[#14][]]

### Added

* Allow multiple citations in a single `@cite` link. In the default numeric style, these can be compressed, e.g. "Refs. [1–3]" [[#6][]]
* In general (depending on the style and citation syntax), citation links may now render to arbitrarily complex expressions.
* Citation comments can now have inline markdown elements, e.g., `[GoerzQ2022; definition of $J$ in section *Running costs*](@cite)`
* When running in non-strict mode, missing bibliographic references (either because the `.bib` file does not contain an entry with a specific BibTeX key, or because of a missing `@biblography` block) are now handled similarly to missing references in LaTeX: They will show as (unlinked) question marks.

### Internal Changes

* Removed the redundant `CitationLink.link_text` field.
* Added `read_citation_link` replacing the former `CitationLink` constructor.
* `CitationLink` can now be instantiated directly from markdown strings (for documentation / testing purposes)
* Added `DirectCitationLink` type to represent citations of the form `[text](@cite key)`.
* Exposed `CitationLink` to users who want to implement a custom style (see changes in `format_citation`)
* The interface for the `format_citation` function has changed: Before, the signature was `format_citation(style, entry, citations; note, cite_cmd, capitalize, starred)` and the function would return as string that would replace the link text of the citation link. Now, the signature is `format_citation(style, cit, entries, citations)` where `cit` is a `CitationLink` object, and the function returns a string of markdown code that replaces the *entire* citation link (not just the link text). Generally, the returned markdown code is expected to contain *direct* citation links which, are automatically expanded subsequently. That is, `format_citation` now generally converts indirect citation links (`CitationLink`) into direct citation links (`DirectCitationLink`).
* Exposed the internal function `format_labeled_citation` that implements `format_citation` for the built-in styles `:numeric` and `:alpha` and may be useful for custom styles that are variations of these.
* Exposed the internal function `format_authoryear_citation` that implements `format_citation` for the built-in style `:authoryear`
* Exposed the internal function `format_labeled_bibliography_reference` that implements `format_bibliography_reference` for the built-in styles `:numeric` and `:alpha`.
* Exposed the internal function `format_authoryear_bibliography_reference` that implements `format_bibliography_reference` for the built-in style `:authoryear:`.
* The example custom styles `:enumauthoryear` and `:keylabels` have been rewritten using the above internal functions, illustrating that custom styles will usually not have to rely on the undocumented and even more internal functions like `format_names` and `tex2unicode`.


## [Version 1.2.1][1.2.1] - 2023-09-22

Expand Down Expand Up @@ -87,8 +113,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#39]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/39
[#36]: https://github.com/JuliaDocs/DocumenterCitations.jl/pull/36
[#35]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/35
[#34]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/34
[#32]: https://github.com/JuliaDocs/DocumenterCitations.jl/pull/32
[#31]: https://github.com/JuliaDocs/DocumenterCitations.jl/pull/31
[#20]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/20
[#19]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/19
[#16]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/16
[#14]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/14
[#6]: https://github.com/JuliaDocs/DocumenterCitations.jl/issues/6
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
AbstractTrees = "^0.4"
Bibliography = "^0.2"
Documenter = "1"
MarkdownAST = "^0.1"
MarkdownAST = "0.1.2"
OrderedCollections = "1"
julia = "^1.6"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

[DocumenterCitations.jl](https://github.com/JuliaDocs/DocumenterCitations.jl#readme) uses [Bibliography.jl](https://github.com/Humans-of-Julia/Bibliography.jl) to add support for BibTeX citations in documentation pages generated by [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl).

By default, [DocumenterCitations.jl](https://github.com/JuliaDocs/DocumenterCitations.jl#readme) uses a numeric citation style common in the natural sciences, see e.g. the [journals of the American Physical Society](https://journals.aps.org), and the [REVTeX author's guide](https://www.ctan.org/tex-archive/macros/latex/contrib/revtex/auguide). Citations are shown in-line, as a number enclosed in square brackets, e.g., "Optimal control is a cornerstone in the development of quantum technologies [[1]](#screenshot)."
By default, [DocumenterCitations.jl](https://github.com/JuliaDocs/DocumenterCitations.jl#readme) uses a numeric citation style common in the natural sciences, see e.g. the [journals of the American Physical Society](https://journals.aps.org), and the [REVTeX author's guide](https://www.ctan.org/tex-archive/macros/latex/contrib/revtex/auguide). Citations are shown in-line, as a number enclosed in square brackets, e.g., "Optimal control is a cornerstone in the development of quantum technologies [[1](#screenshot)]."


<img id="screenshot" src="docs/src/assets/references.png" alt="Rendered bibliography of two references, [1] and [2]" width="830px">
Expand Down Expand Up @@ -58,7 +58,7 @@ to the `[deps]` section of the relevant `Project.toml` file.

that will expand into a bibliography for all citations in the documentation.

* Anywhere in the documentation or in docstrings, insert citations as, e.g., `[GoerzQ2022](@cite)`, which will be rendered as "[[2]](#screenshot)" and link to the full reference in the bibliography.
* Anywhere in the documentation or in docstrings, insert citations as, e.g., `[GoerzQ2022](@cite)`, which will be rendered as "[[2](#screenshot)]" and link to the full reference in the bibliography.

See the [documentation](https://juliadocs.github.io/DocumenterCitations.jl) for additional information.

Expand Down
11 changes: 7 additions & 4 deletions docs/custom_styles/enumauthoryear.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import DocumenterCitations

function DocumenterCitations.format_bibliography_reference(::Val{:enumauthoryear}, entry)
text = DocumenterCitations.format_bibliography_reference(:authoryear, entry)
function DocumenterCitations.format_bibliography_reference(
style::Val{:enumauthoryear},
entry
)
text = DocumenterCitations.format_authoryear_bibliography_reference(style, entry)
return uppercasefirst(text)
end

DocumenterCitations.format_citation(::Val{:enumauthoryear}, args...; kwargs...) =
DocumenterCitations.format_citation(:authoryear, args...; kwargs...)
DocumenterCitations.format_citation(style::Val{:enumauthoryear}, args...) =
DocumenterCitations.format_authoryear_citation(style, args...)

DocumenterCitations.bib_sorting(::Val{:enumauthoryear}) = :nyt # name, year, title

Expand Down
37 changes: 15 additions & 22 deletions docs/custom_styles/keylabels.jl
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
import DocumenterCitations, MarkdownAST
import DocumenterCitations

# we use some (undocumented) internal helper functions for formatting...
using DocumenterCitations: format_names, tex2unicode

DocumenterCitations.format_bibliography_reference(::Val{:keylabels}, entry) =
DocumenterCitations.format_bibliography_reference(:numeric, entry)
DocumenterCitations.format_bibliography_reference(style::Val{:keylabels}, entry) =
DocumenterCitations.format_labeled_bibliography_reference(style, entry)

function DocumenterCitations.format_bibliography_label(::Val{:keylabels}, entry, citations)
return "[$(entry.id)]"
end

function DocumenterCitations.format_citation(
style::Val{:keylabels},
entry,
citations;
note,
cite_cmd,
capitalize,
starred
cit,
entries,
citations
)
link_text = isnothing(note) ? "[$(entry.id)]" : "[$(entry.id), $note]"
if cite_cmd == :citet
et_al = starred ? 0 : 1 # 0: no "et al."; 1: "et al." after 1st author
names =
format_names(entry; names=:lastonly, and=true, et_al, et_al_text="*et al.*") |>
tex2unicode
capitalize && (names = uppercase(names[1]) * names[2:end])
link_text = "$names $link_text"
end
return link_text::String
return DocumenterCitations.format_labeled_citation(style, cit, entries, citations)
# The only difference compared to `:alpha` is the citation label, which is
# picked up automatically by redefining `citation_label` below.
end


function DocumenterCitations.citation_label(style::Val{:keylabels}, entry, citations; _...)
return entry.id
end


DocumenterCitations.bib_sorting(::Val{:keylabels}) = :nyt # name, year, title

DocumenterCitations.bib_html_list_style(::Val{:keylabels}) = :dl
2 changes: 1 addition & 1 deletion docs/latex/alpha.tex
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliographystyle{alpha}
\bibliography{../src/refs}
\bibliography{refs}

\end{document}
6 changes: 4 additions & 2 deletions docs/latex/authoryear.tex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
\usepackage[
pdftitle={\Title},
pdfauthor={\Author},
colorlinks=true, linkcolor=black, urlcolor=black, citecolor=black,
colorlinks=true, linkcolor=magenta, urlcolor=black, citecolor=magenta,
bookmarksopen=false, breaklinks=true, plainpages=false, pdfpagelabels
]{hyperref}

Expand Down Expand Up @@ -47,10 +47,12 @@
\item \verb|\Citet{WinckelIP2008}| renders as ``\Citet{WinckelIP2008}''.
\item \verb|\Citealt{WinckelIP2008}| renders as ``\Citealt{WinckelIP2008}''.
\item \verb|\Citealp{WinckelIP2008}| renders as ``\Citealp{WinckelIP2008}''.
\item multi-\verb|\cite|: See~\cite[and references therein]{WinckelIP2008,BrumerShapiro2003,BrifNJP2010,Shapiro2012,KochJPCM2016,GoerzQ2022,SolaAAMOP2018,MorzhinRMS2019,KochEPJQT2022}
\item multi-\verb|\citet|: See~\citet[and references therein]{WinckelIP2008,BrumerShapiro2003,BrifNJP2010,Shapiro2012,KochJPCM2016,GoerzQ2022,SolaAAMOP2018,MorzhinRMS2019,KochEPJQT2022}.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliography{../src/refs}
\bibliography{refs}

\end{document}
5 changes: 3 additions & 2 deletions docs/latex/numeric.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
\usepackage[
pdftitle={\Title},
pdfauthor={\Author},
colorlinks=true, linkcolor=black, urlcolor=black, citecolor=black,
colorlinks=true, linkcolor=magenta, urlcolor=black, citecolor=magenta,
bookmarksopen=false, breaklinks=true, plainpages=false, pdfpagelabels
]{hyperref}

Expand Down Expand Up @@ -38,6 +38,7 @@
\item \verb|\citet{WinckelIP2008}| renders as ``\citet{WinckelIP2008}''.
\item \verb|\Citet{WinckelIP2008}| renders as ``\Citet{WinckelIP2008}''.
\item \cite{GoerzPhd2015} and \cite{Luc-KoenigEPJD2004}
\item Refs.~\cite[and references therein]{WinckelIP2008,BrumerShapiro2003,BrifNJP2010,Shapiro2012,KochJPCM2016,GoerzQ2022,SolaAAMOP2018,MorzhinRMS2019,KochEPJQT2022}.
\end{itemize}

Further commands that we do not support in markdown:
Expand All @@ -56,6 +57,6 @@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliography{../src/refs}
\bibliography{refs}

\end{document}
2 changes: 1 addition & 1 deletion docs/latex/prb.tex
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliography{../src/refs}
\bibliography{refs}

\end{document}
119 changes: 119 additions & 0 deletions docs/latex/refs.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
@string{ip = "Inverse Problems"}
@string{quant = "Quantum"}
@string{njp = "New J. Phys."}
@string{rms = "Russ. Math. Surv."}
@string{epjqt = "EPJ Quantum Technol."}
@string{epjd = "Eur. Phys. J. D"}


@article{GoerzQ2022,
Author = {Goerz, Michael H. and Carrasco, Sebastián C. and Malinovsky, Vladimir S.},
Title = {Quantum Optimal Control via Semi-Automatic Differentiation},
Journal = quant,
Year = {2022},
Doi = {10.22331/q-2022-12-07-871},
Pages = {871},
Volume = {6},
}

@article{WinckelIP2008,
Author = {von Winckel, G and Borzì, A},
Title = {Computational techniques for a quantum control problem with H$^1$-cost},
Journal = ip,
Year = {2008},
Doi = {10.1088/0266-5611/24/3/034007},
Pages = {034007},
Volume = {24},
}

@book{BrumerShapiro2003,
author = {Brumer, P and Shapiro, M.},
publisher = {Wiley Interscience},
title = {Principles and Applications of the Quantum Control of Molecular Processes},
year = {2003}
}

@article{BrifNJP2010,
Author = {Brif, Constantin and Chakrabarti, Raj and Rabitz, Herschel},
Title = {Control of quantum phenomena: past, present and future},
Journal = njp,
Year = {2010},
Doi = {10.1088/1367-2630/12/7/075008},
Pages = {075008},
Volume = {12},
}

@book{Shapiro2012,
author = {Shapiro, Moshe and Brumer, Paul},
edition = {Second},
publisher = {Wiley and Sons},
series = { },
title = {Quantum Control of Molecular Processes},
year = {2012},
Doi = {10.1002/9783527639700},
}

@article{KochJPCM2016,
author={Christiane P. Koch},
title={Controlling open quantum systems: tools, achievements, and limitations},
journal={J. Phys.: Condens. Matter},
volume={28},
pages={213001},
doi={10.1088/0953-8984/28/21/213001},
year={2016},
}

@incollection{SolaAAMOP2018,
author = {Sola, Ignacio R. and Chang, Bo Y. and Malinovskaya, Svetlana A. and Malinovsky, Vladimir S.},
booktitle = {Advances In Atomic, Molecular, and Optical Physics},
chapter = {3},
doi = {10.1016/bs.aamop.2018.02.003},
editor = {Arimondo, Ennio and DiMauro, Louis F. and Yelin, Susanne F.},
pages = {151-256},
publisher = {Academic Press},
title = {Quantum Control in Multilevel Systems},
volume = {67},
year = {2018},
}

@article{MorzhinRMS2019,
Author = {Morzhin, Oleg V. and Pechen, Alexander N.},
Title = {Krotov method for optimal control of closed quantum systems},
Journal = rms,
Year = {2019},
Doi = {10.1070/rm9835},
Pages = {851},
Volume = {74},
}

@article{KochEPJQT2022,
Author = {Koch, Christiane P. and Boscain, Ugo and Calarco, Tommaso and Dirr, Gunther and Filipp, Stefan and Glaser, Steffen J. and Kosloff, Ronnie and Montangero, Simone and Schulte-Herbrüggen, Thomas and Sugny, Dominique and Wilhelm, Frank K.},
Title = {Quantum optimal control in quantum technologies. Strategic report on current status, visions and goals for research in {Europe}},
Journal = epjqt,
Year = {2022},
Doi = {10.1140/epjqt/s40507-022-00138-x},
Pages = {19},
Volume = {9},
}

@article{Luc-KoenigEPJD2004,
Author = {Luc-Koenig, E. and Vatasescu, M. and Masnou-Seeuws, F.},
Title = {Optimizing the photoassociation of cold atoms by use of chirped laser pulses},
Journal = epjd,
Year = {2004},
Doi = {10.1140/epjd/e2004-00161-8},
Pages = {239},
Volume = {31},
Number = {2},
eprint = {physics/0407112},
primaryClass = {physics.atm-clus},
Archiveprefix = {arXiv},
}

@phdthesis{GoerzPhd2015,
Author = {Goerz, Michael},
Title = {Optimizing Robust Quantum Gates in Open Quantum Systems},
School = {Universität Kassel},
url = {https://kobra.uni-kassel.de/handle/123456789/2015052748381},
Year = {2015},
}
6 changes: 4 additions & 2 deletions docs/latex/rmp.tex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
\usepackage[
pdftitle={\Title},
pdfauthor={\Author},
colorlinks=true, linkcolor=black, urlcolor=black, citecolor=black,
colorlinks=true, linkcolor=magenta, urlcolor=black, citecolor=magenta,
bookmarksopen=false, breaklinks=true, plainpages=false, pdfpagelabels
]{hyperref}

Expand All @@ -37,6 +37,8 @@
\item \verb|\citep*[Eq.~(1)]{GoerzQ2022}| renders as ``\citep*[Eq.~(1)]{GoerzQ2022}''.
\item \verb|\citet{WinckelIP2008}| renders as ``\citet{WinckelIP2008}''.
\item \verb|\Citet{WinckelIP2008}| renders as ``\Citet{WinckelIP2008}''.
\item multi-\verb|\cite|: See~\cite[and references therein]{WinckelIP2008,BrumerShapiro2003,BrifNJP2010,Shapiro2012,KochJPCM2016,GoerzQ2022,SolaAAMOP2018,MorzhinRMS2019,KochEPJQT2022}
\item multi-\verb|\citet|: See~\citet[and references therein]{WinckelIP2008,BrumerShapiro2003,BrifNJP2010,Shapiro2012,KochJPCM2016,GoerzQ2022,SolaAAMOP2018,MorzhinRMS2019,KochEPJQT2022}.
\end{itemize}

Further commands that we do not support in markdown:
Expand All @@ -55,6 +57,6 @@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bibliography{../src/refs}
\bibliography{refs}

\end{document}
6 changes: 6 additions & 0 deletions docs/src/gallery.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ This is the default style (`style=:numeric`) used throughout the other pages of
* `[GoerzQ2022; Eq. (1)](@citet*)` renders as "[GoerzQ2022; Eq. (1)](@citet*)"
* `[WinckelIP2008](@citet)` renders as "[WinckelIP2008](@citet)"
* `[WinckelIP2008](@Citet)` renders as "[WinckelIP2008](@Citet)"
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite)"
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet)"
* `[arbitrary text](@cite GoerzQ2022)` renders as "[arbitrary text](@cite GoerzQ2022)"

**References:**
Expand All @@ -48,6 +50,8 @@ The author-year style (`style=:authoryear`) formats citations with the author na
* `[GoerzQ2022; Eq. (1)](@citet*)` renders as "[GoerzQ2022; Eq. (1)](@citet*%authoryear%)"
* `[WinckelIP2008](@citet)` renders as "[WinckelIP2008](@citet%authoryear%)"
* `[WinckelIP2008](@Citet)` renders as "[WinckelIP2008](@Citet%authoryear%)"
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite%authoryear%)"
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet%authoryear%)"
* `[arbitrary text](@cite GoerzQ2022)` renders as "[arbitrary text](@cite GoerzQ2022)"

**References:**
Expand All @@ -72,6 +76,8 @@ The `style=:alpha` formats citations and references like `:numeric`, except that
* `[GoerzQ2022; Eq. (1)](@citet*)` renders as "[GoerzQ2022; Eq. (1)](@citet*%alpha%)"
* `[WinckelIP2008](@citet)` renders as "[WinckelIP2008](@citet%alpha%)"
* `[WinckelIP2008](@Citet)` renders as "[WinckelIP2008](@Citet%alpha%)"
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@cite%alpha%)". Note that unlike for `style=:numeric`, the citations are not compressed.
* `[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet)` renders as "[BrumerShapiro2003, BrifNJP2010, Shapiro2012, KochJPCM2016; and references therein](@Citet%alpha%)"
* `[arbitrary text](@cite GoerzQ2022)` renders as "[arbitrary text](@cite GoerzQ2022)"

**References:**
Expand Down
Loading

0 comments on commit 06a54f7

Please sign in to comment.