Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DejaVu fonts in PDF builds #1066

Merged
merged 5 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

* ![Enhancement][badge-enhancement] Videos can now be included in the HTML output using the image syntax (`![]()`) if the file extension matches a known format (`.webm`, `.mp4`, `.ogg`, `.ogm`, `.ogv`, `.avi`). ([#1034][github-1034])

* ![Enhancement][badge-enhancement] The PDF output now uses the DejaVu Sans and DejaVu Sans Mono fonts to provide better Unicode coverage. ([#803][github-803], [#1066][github-1066])

* ![Bugfix][badge-bugfix] The HTML output now outputs HTML files for pages that are not referenced in the `pages` keyword too (Documenter finds them according to their extension). But they do exists outside of the standard navigation hierarchy (as defined by `pages`). This fixes a bug where these pages could still be referenced by `@ref` links and `@contents` blocks, but in the HTML output, the links ended up being broken. ([#1031][github-1031], [#1047][github-1047])

* ![Bugfix][badge-bugfix] `makedocs` now throws an error when the format objects (`Documenter.HTML`, `LaTeX`, `Markdown`) get passed positionally. The format types are no longer subtypes of `Documenter.Plugin`. ([#1046][github-1046], [#1061][github-1061])
Expand Down Expand Up @@ -308,6 +310,7 @@
[github-794]: https://github.com/JuliaDocs/Documenter.jl/pull/794
[github-795]: https://github.com/JuliaDocs/Documenter.jl/pull/795
[github-802]: https://github.com/JuliaDocs/Documenter.jl/pull/802
[github-803]: https://github.com/JuliaDocs/Documenter.jl/issues/803
[github-804]: https://github.com/JuliaDocs/Documenter.jl/pull/804
[github-813]: https://github.com/JuliaDocs/Documenter.jl/pull/813
[github-816]: https://github.com/JuliaDocs/Documenter.jl/pull/816
Expand Down Expand Up @@ -375,6 +378,7 @@
[github-1054]: https://github.com/JuliaDocs/Documenter.jl/pull/1054
[github-1061]: https://github.com/JuliaDocs/Documenter.jl/pull/1061
[github-1062]: https://github.com/JuliaDocs/Documenter.jl/pull/1062
[github-1066]: https://github.com/JuliaDocs/Documenter.jl/pull/1066

[documenterlatex]: https://github.com/JuliaDocs/DocumenterLaTeX.jl
[documentermarkdown]: https://github.com/JuliaDocs/DocumenterMarkdown.jl
Expand Down
9 changes: 7 additions & 2 deletions assets/latex/documenter.sty
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
% font settings
\usepackage{fontspec, newunicodechar, polyglossia}

\setsansfont{Lato}[Scale=MatchLowercase, Ligatures=TeX]
\setmonofont{Roboto Mono}[Scale=MatchLowercase]
\setsansfont{DejaVu Sans}[Scale=MatchLowercase, Ligatures=TeX]
\setmonofont{DejaVu Sans Mono}[Scale=MatchLowercase]
\renewcommand{\familydefault}{\sfdefault}
% DejaVu Sans Mono does not have the xor symbol. So we hack around that by replacing all
% instances of it with calls to \unicodeveebar, which prints this single character as with
% DejaVu Sans instead.
\newfontfamily\unicodeveebarfont{DejaVu Sans}[Scale=MatchLowercase]
\newcommand\unicodeveebar{{\unicodeveebarfont ⊻}}
%

% colours
Expand Down
3 changes: 1 addition & 2 deletions docs/src/man/other-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ The following is required to build the documentation:
* You need `pdflatex` command to be installed and available to Documenter.
* You need the [minted](https://ctan.org/pkg/minted) LaTeX package and its backend source
highlighter [Pygments](http://pygments.org/) installed.
* You need the [Lato](http://www.latofonts.com/lato-free-fonts/) and
[Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) fonts installed.
* You need the [_DejaVu Sans_ and _DejaVu Sans Mono_](https://dejavu-fonts.github.io/) fonts installed.

### Compiling using docker image

Expand Down
36 changes: 30 additions & 6 deletions src/Writers/LaTeXWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ function render(doc::Documents.Document, settings::LaTeX=LaTeX())
# compile .tex and copy over the .pdf file if compile_tex return true
status = compile_tex(doc, settings, texfile)
status && cp(pdffile, joinpath(doc.user.root, doc.user.build, pdffile); force = true)

# Debug: if DOCUMENTER_LATEX_DEBUG environment variable is set, copy the LaTeX
# source files over to a directory under doc.user.root.
if haskey(ENV, "DOCUMENTER_LATEX_DEBUG")
sources = cp(pwd(), mktempdir(doc.user.root), force=true)
@info "LaTeX sources copied for debugging to $(sources)"
end
end
end
end
Expand Down Expand Up @@ -391,23 +398,38 @@ function latex(io::IO, code::Markdown.Code)
# the julia-repl is called "jlcon" in Pygments
language = (language == "julia-repl") ? "jlcon" : language
if language in LEXER
_print(io, "\n\\begin{minted}")
_print(io, "\n\\begin{minted}[escapeinside=\\%\\%]")
_println(io, "{", language, "}")
_println(io, code.code)
_print_code_escapes(io, code.code)
_println(io, "\\end{minted}\n")
else
_println(io, "\n\\begin{lstlisting}")
_println(io, code.code)
_println(io, "\n\\begin{lstlisting}[escapeinside=\\%\\%]")
_print_code_escapes(io, code.code)
_println(io, "\\end{lstlisting}\n")
end
end

function _print_code_escapes(io, s::AbstractString)
for ch in s
ch === '%' ? _print(io, "%\\%%") :
ch === '⊻' ? _print(io, "%\\unicodeveebar%") :
_print(io, ch)
end
end

function latexinline(io::IO, code::Markdown.Code)
_print(io, "\\texttt{")
latexesc(io, code.code)
_print_code_escapes_inline(io, code.code)
_print(io, "}")
end

function _print_code_escapes_inline(io, s::AbstractString)
for ch in s
ch === '⊻' ? _print(io, "\\unicodeveebar{}") :
latexesc(io, ch)
end
end

function latex(io::IO, md::Markdown.Paragraph)
for md in md.content
latexinline(io, md)
Expand Down Expand Up @@ -605,9 +627,11 @@ for ch in "&%\$#_{}"
_latexescape_chars[ch] = "\\$ch"
end

latexesc(io, ch::AbstractChar) = _print(io, get(_latexescape_chars, ch, ch))

function latexesc(io, s::AbstractString)
for ch in s
_print(io, get(_latexescape_chars, ch, ch))
latexesc(io, ch)
end
end

Expand Down
3 changes: 2 additions & 1 deletion test/examples/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ htmlbuild_pages = Any[
"expandorder/00.md",
"expandorder/01.md",
"expandorder/AA.md",
]
],
"unicode.md",
]

@info("Building mock package docs: HTMLWriter / local build")
Expand Down
113 changes: 113 additions & 0 deletions test/examples/src/unicode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Unicode

Some unicode tests here.

In main sans-serif font:

* Checkmark: "✓"
* Cicled plus: "⊕"
* XOR: "⊻"
* Exists: "∀", forall: "∃"

`\begin{lstlisting}` is used for non-highlighted blocks:

```
xor: ⊻
forall: ∀
exists: ∃
check: ✓
oplus: ⊕

What about the other edge cases: \ % \% %\ %% %\%%
```

`\begin{minted}` is used for highlighted blocks:

```julia
xor: ⊻
forall: ∀
exists: ∃
check: ✓
oplus: ⊕
```

Inlines:

`xor: ⊻ -> %\unicodeveebar% <-`

`forall: ∀, exists: ∃, check: ✓`

`%\%%\unicodeveebar, oplus: ⊕`

## Drawings etc

```
┌────────────────────────────────────────────────────────────────────────────┐
│ ┌───────────────┐ │
│ HTTP.request(method, uri, headers, body) -> │ HTTP.Response ├──────────────┼┐
│ │ └───────────────┘ ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ┌──────────────────┐ ││
│ └───▶│ request(RedirectLayer, ...) │ │ HTTP.StatusError │ ││
│ └─┬────────────────────────────────────┴─┐ └─────────▲────────┘ ││
│ │ request(BasicAuthLayer, ...) │ │ ││
│ └─┬────────────────────────────────────┴─┐ │ ││
│ │ request(CookieLayer, ...) │ │ ││
│ └─┬────────────────────────────────────┴─┐ │ ││
│ │ request(CanonicalizeLayer, ...) │ │ ││
│ └─┬────────────────────────────────────┴─┐ │ ││
│ │ request(MessageLayer, ...) ├─────────┼──────┐ ││
```

```julia
┌──────────────────────────────────────────────────────────────────────┐
1 │ ▗▄▞▀▀▀▀▀▀▀▄▄ │
│ ▄▞▘ ▀▄▖ │
│ ▄▀ ▝▚▖ │
│ ▗▞ ▝▄ │
│ ▞▘ ▝▚▖ │
│ ▗▀ ▝▚ │
│ ▞▘ ▀▖ │
│ ▗▞ ▝▄ │
│ ▄▘ ▚▖ │
│ ▗▞ ▝▄ │
│ ▄▘ ▚▖ │
│ ▗▀ ▝▚ │
│ ▗▞▘ ▀▄ │
│ ▄▀▘ ▀▚▖ │
0 │ ▄▄▄▄▀▀ ▝▀▚▄▄▄▖│
└──────────────────────────────────────────────────────────────────────┘
0 70
```

```
2×4 DataFrames.DataFrame
│ Row │ a │ b │ c │ d │
│ │ Int64 │ Float64 │ Int64 │ String │
├─────┼───────┼─────────┼───────┼────────┤
│ 1 │ 2 │ 2.0 │ 2 │ John │
│ 2 │ 2 │ 2.0 │ 2 │ Sally │
```

```julia
function map_filter_iterators(xs, init)
ret = iterate(xs)
ret === nothing && return
acc = init
@goto filter
local state, x
while true
while true # input
ret = iterate(xs, state) #
ret === nothing && return acc #
@label filter #
x, state = ret #
iseven(x) && break # filter :
end # :
y = 2x # imap : :
acc += y # + : : :
end # : : : :
# + <-- imap <-------- filter <-- input
return acc
end
```
2 changes: 1 addition & 1 deletion test/examples/tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ end

@test realpath(doc.internal.assets) == realpath(joinpath(dirname(@__FILE__), "..", "..", "assets"))

@test length(doc.blueprint.pages) == 14
@test length(doc.blueprint.pages) == 15

let headers = doc.internal.headers
@test Documenter.Anchors.exists(headers, "Documentation")
Expand Down