Added `bundles` directory
This commit is contained in:
parent
bab45fc1eb
commit
ed60761808
|
@ -0,0 +1,58 @@
|
|||
# Tectonic Bundles
|
||||
|
||||
This repository contains tools for building bundles for [Tectonic](https://tectonic-typesetting.github.io).
|
||||
You should only need this if you're producing your own bundles. If you're just using Tectonic to compile LaTeX,
|
||||
you should use the pre-generated bundles we distribute.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
To use these tools, you will need:
|
||||
- GNU `patch`. Patch is called by `tectonic bundle create `.
|
||||
- A [TeXlive tarball](https://tug.org/texlive/acquire-tar.html).
|
||||
|
||||
The following bundles are available:
|
||||
- [`texlive2023`](./bundles/texlive2023): based on `texlive2023-20230313`.
|
||||
|
||||
|
||||
## Build Process:
|
||||
Before building any bundles, you'll need to download the prerequisite files.
|
||||
Usually, this is a [TeXlive tarball](https://tug.org/texlive/acquire-tar.html) with a version that matches the bundle you want to build.
|
||||
See `bundle.toml` in the bundle you want to build.
|
||||
|
||||
|
||||
To build a bundle, run the following:
|
||||
- `cd bundles`
|
||||
- `tectonic -X bundle create --build-dir ./build texlive2023/bundle.toml v1`
|
||||
|
||||
This runs the following jobs, in order. Individual jobs may be run by specifying `--job <job name>`.
|
||||
- `select`
|
||||
- `pack`
|
||||
|
||||
The contents of `<build dir>/content` may be inspected and edited after running `select`. \
|
||||
This should only be used to debug bundles.
|
||||
|
||||
|
||||
## Extra Documentation
|
||||
- Each directory in [`./bundles`](./bundles/) is a bundle specification, documented [here](./bundles/README.md).
|
||||
- Only one bundle format is currently supported, it is described in [`./format-v1.md`](./format-v1.md).
|
||||
- This repository includes legacy bundle [tests](./tests/README.md), which may be broken.
|
||||
|
||||
|
||||
## Output files
|
||||
|
||||
The files that `tectonic bundle create` produces are listed below:
|
||||
- `./build/output/<bundle>/content`: contains all bundle files. It is organized by source: files from the bundle's `include` dir will be under `./include`, texlive files will be under `./texlive`, and so on. See `builder/src/select.rs`.
|
||||
This directory also contains some metadata:
|
||||
- `content/FILELIST`: each line of this file is `<path> <hash>`, sorted by file name.\
|
||||
Files with identical names are included.\
|
||||
Files not in any search path are also included.\
|
||||
`<hash>` is either a hex sha256 of that file's contents, or `nohash` for a few special files.
|
||||
- `content/SHA256SUM`: The sha256sum of `content/FILES`. This string uniquely defines this bundle.
|
||||
- `content/SEARCH`: File search order for this bundle. See bundle spec documentation.
|
||||
- `search-report`: debug file. Lists all directories that will not be searched by the rules in `search-order`.\
|
||||
The entries in this file are non-recursive: If `search-report` contains a line with `/texlive`, this means that direct children of `/texlive` (like `/texlive/file.tex`) will not be found, but files in *subdirectories* (like `/texlive/tex/file.tex`) may be.
|
||||
|
||||
**Final output files are listed below:**
|
||||
- `<bundle>.ttb`: the bundle. Note that the ttb version is *not* included in the extension.
|
||||
- Index location and length are printed once this job completes.
|
||||
- You can extract files from this bundle by running `dd if=file.ttb ibs=1 skip=<start> count=<len> | gunzip`
|
|
@ -0,0 +1,3 @@
|
|||
# Ignore build files & resources
|
||||
/build
|
||||
*.tar
|
|
@ -0,0 +1,166 @@
|
|||
# Bundle Specification
|
||||
|
||||
Every directory in this dir defines a Tectonic bundle.
|
||||
The main configuration file is `bundle.toml`, its contents are documented below.
|
||||
|
||||
## Overview
|
||||
|
||||
```toml
|
||||
[bundle]
|
||||
# This bundle's name
|
||||
name = "texlive2023"
|
||||
# This bundle's expected final SHA256 hash. See the bundle specification to learn how it's generated.
|
||||
# If this is left empty, the bundle hash will be printed once the bundle is built.
|
||||
expected_hash = "c1bbb5f8498d2bb5471cc2b0790700ecb86fc992ec290f7eb718d8751f8ada2a"
|
||||
|
||||
# Bundle search order. This tells Tectonic how to search for files.
|
||||
# The global `search_order` may have two kinds of values:
|
||||
# - plain strings (which follow the usual search order rules)
|
||||
# - `{ input = "" }` entries, which specify an input's search order.
|
||||
# If an input is not listed here, it will NOT be searched!
|
||||
# (unless one specifies "//", which is a bad idea.)
|
||||
#
|
||||
# This is used to generate SEARCH in the bundle.
|
||||
search_order = ["/", { input = "include" }, { input = "texlive" }]
|
||||
|
||||
# Note the triple-quoted multiline strings:
|
||||
# this is the best way to get raw strings in TOML.
|
||||
ignore = [
|
||||
# Files and extensions we want to ignore.
|
||||
# These will be applied to ALL inputs.
|
||||
# If a file's relative path matches any of these patterns,
|
||||
# that file will be excluded from the bundle.
|
||||
'''.*/LICENSE\.md''',
|
||||
'''.*/Makefile''',
|
||||
'''.*/README''',
|
||||
'''.*/README.md''',
|
||||
'''.*/readme\.txt'''
|
||||
]
|
||||
|
||||
|
||||
# A simple directory input, with `path` relative to this toml file.
|
||||
[inputs."include"]
|
||||
source.dir.path = "include"
|
||||
|
||||
|
||||
# A tarball input, usually used to add TeXlive files.
|
||||
#
|
||||
# Note that this MUST be a .tar file.
|
||||
# You'll likely download a compressed tar file. Extract it.
|
||||
#
|
||||
# It's a good idea to add a comment with the TeXlive version
|
||||
# and url of this file, so that others may find it.
|
||||
[inputs."texlive"]
|
||||
|
||||
# Patch directory for this input. Optional.
|
||||
# This should be a directory of `.diff` files in unified format,
|
||||
# the first line of which specifies the path (relative to `root_dir` below)
|
||||
# of the file that diff should be applied to.
|
||||
#
|
||||
#
|
||||
# To make a patch file, you should...
|
||||
# - Copy the original file and apply your changes.
|
||||
# - Run `diff "original-file" "modified-file" > file.diff`. ORDER MATTERS!
|
||||
# - Add **one** new line to the top of `file.diff` containing a path to the file this diff should be applied to. This path should be relative to the bundle's content dir, as shown below.
|
||||
# - Place `file.diff` anywhere in your bundle's include dir. The file selection script should find and apply it.
|
||||
#
|
||||
# The line at the top is essential and must be added manually.
|
||||
# We can't do without it, since we may have many files with # the same name.
|
||||
#
|
||||
# Also note that the brace decorations used in `search_order` may also be used in this first line.
|
||||
# For example, a patch marked `tex/{latex,latex-dev}/base/latex.ltx` will be applied to `latex.ltx` in both
|
||||
# `texlive/tex/latex` and `texlive/tex/latex-dev`. This will only work if those files are identical.
|
||||
patch_dir = "patches/texlive"
|
||||
|
||||
|
||||
# Path to the tarball, relative to this toml file's parent directory.
|
||||
source.tarball.path = "texlive-20230313-texmf.tar"
|
||||
|
||||
# Compute this hash by running `sha256 -b file.tar`
|
||||
source.tarball.hash = "ac1683d4abeb7fd534851ad7ff0ec891da7da4729603506efd0245259dcdcc67"
|
||||
|
||||
# The directory inside this tarball to add. Optional.
|
||||
# All paths below are relative to this.
|
||||
source.tarball.root_dir = "texlive-20230313-texmf/texmf-dist"
|
||||
|
||||
# Regex ignore pattens. Any file whose path matches any of these patterns will not be added to the bundle.
|
||||
# These are relative to `root_dir` and do NOT start with a slash.
|
||||
ignore = [
|
||||
'''tex/luatex/.*''',
|
||||
'''tex/lualatex/.*'''
|
||||
]
|
||||
|
||||
|
||||
# Search order of this input.
|
||||
# This is optional, ommitting `search_order` is equivalent
|
||||
# to setting `search_order = [ "//" ]`
|
||||
#
|
||||
# As always, these paths are relative to `root_dir` and do NOT start with a slash.
|
||||
#
|
||||
#
|
||||
# Lines may be decorated with braces: `/a/{b,c}/` will become `/a/b` and `a/c`, in that order.
|
||||
# - Brace decorations may not be nested.
|
||||
# - Paths may not contain braces. Escaping with `\{` will not work.
|
||||
# - Multiple brace decorations in one line are allowed:
|
||||
# `/{a,b}/{1,2}` expands to `/a/1`, `/a/2`, `/b/1`, `b/2`, in that order.
|
||||
#
|
||||
# Just like kpathsea search paths, each search pattern can end with one or two slashes.
|
||||
# - If a line ends with two slashes (like `texlive/tex/latex//`), it will match all subdirectories of that path.
|
||||
# - If a line ends with one slash (like `texlive/tex/latex/`), it will match only direct children of that path:
|
||||
# `texlive/tex/latex/a.tex` will be searched, `texlive/tex/latex/base/a.tex` will not.
|
||||
#
|
||||
# - If a line does not end with a slash, we pretend it ends with one.
|
||||
# - If a line ends with three or more slashes, it won't be searched at all. Don't do that.
|
||||
#
|
||||
# This scheme lets us override the default "alphabetic depth-first search" by adding seach paths as follows,
|
||||
# which will look for direct children of `latex` before descending into subdirectories:
|
||||
# ```
|
||||
# texlive/tex/latex/
|
||||
# texlive/tex/latex//
|
||||
# ```
|
||||
search_order = [
|
||||
"tex/{xelatex,latex,xetex,plain,generic}//",
|
||||
"bibtex/{bib,bst,csf}//",
|
||||
"web2c//",
|
||||
"fonts//",
|
||||
"biber//",
|
||||
"mft//",
|
||||
"dvips//",
|
||||
"makeindex//",
|
||||
"{web,cweb}//",
|
||||
"ttf2pk//",
|
||||
"dvipdfmx/",
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Extra details: finding files
|
||||
|
||||
### Overview
|
||||
Any TeX distribution needs a way to find files. This is necessary because files are usually included only by name: `\include{file}`, `\usepackage{package}`, etc. Where do we find `file.tex` and `package.sty`?
|
||||
|
||||
In a conventional TeXLive installation, kpathsea solves this problem. It defines an array of "search paths," and walks through them when you ask for a file. You can find an overview [here](https://www.overleaf.com/learn/latex/Articles/An_introduction_to_Kpathsea_and_how_TeX_engines_search_for_files) and more detailed information in the kpathsea docs.
|
||||
|
||||
Tectonic's supporting files are distributed in bundles, so we can't use the same approach.
|
||||
Within tectonic's *bundles*[^1], we use FILELIST and SEARCH files to map a filename to an input path. Note that this logic is implemented in tectonic, not in the bundle build script.
|
||||
|
||||
[^1]: Tectonic searches for files on your disk seperately. The information in this file only applies to bundles. I won't document this fully here, you'll have to read the tectonic docs and source code.
|
||||
|
||||
- **Case 1:** tectonic looks for `file.tex` and finds one path in `FILELIST`\
|
||||
Nothing fancy here, we just use the file we found.
|
||||
|
||||
- **Case 2:** tectonic looks for `partial/path/to/file.tex`\
|
||||
This is an edge case caused by some packages (for example, `fithesis`). To handle this,
|
||||
we first find `file.tex` in `FILELIST` and look at its path. If its path ends with `partial/path/to/file.tex`, we use it,
|
||||
if it doesn't, we don't. If multiple files match, we print an error--that shouldn't ever happen.
|
||||
|
||||
- **Case 3:** tectonic looks for `file.tex` and finds multiple paths in `FILELIST`\
|
||||
This where things get interesting. First, we match all paths against each line of the bundles's `SEARCH` file with a simple `starts_with`.
|
||||
- If *exactly one* path matches a certain line, we immediately stop checking and use that path. Search lines are ordered by priority, so if only one path matches the first line, it *must* be the right path to use.
|
||||
- If multiple paths match a certain line, we discard all others and resolve the conflict alphabetically.
|
||||
- If we've checked all lines of `SEARCH` and found no matches, we didn't find the file. Return an error.
|
||||
|
||||
"Resolving the conflict alphabetically" means we sort the paths in alphabetical order and pick the first. This emulates an alphabetically-ordered depth-first search on the file tree, which is a reasonable default.
|
||||
|
||||
Any filename conflicts which would be resolved alphabetically are listed in `search-report` after the `select` build step. These aren't errors, but we should look over that file to make sure everything is working as expected.
|
|
@ -0,0 +1,89 @@
|
|||
[bundle]
|
||||
name = "texlive2023"
|
||||
expected_hash = "e2571849ee65f1c8cb6dc7e433a1ae6b97b47eb24d27074cd485ff2bb87a79ab"
|
||||
|
||||
search_order = ["/", { input = "include" }, { input = "texlive" }]
|
||||
|
||||
# Note the triple-quoted multiline strings:
|
||||
# this is the best way to get raw strings in TOML.
|
||||
ignore = [
|
||||
# Files and extensions we usually want to ignore.
|
||||
'''.*/00readme\.txt''',
|
||||
'''.*/LICENSE\.md''',
|
||||
'''.*/Makefile''',
|
||||
'''.*/README''',
|
||||
'''.*/README.md''',
|
||||
'''.*/readme\.txt''',
|
||||
'''.*/ls-R''',
|
||||
'''.*\.fmt''',
|
||||
'''.*\.log''',
|
||||
'''.*\.lua''',
|
||||
'''.*\.mf''',
|
||||
'''.*\.pl''',
|
||||
'''.*\.ps''',
|
||||
]
|
||||
|
||||
|
||||
[inputs."include"]
|
||||
source.dir.path = "include"
|
||||
|
||||
|
||||
# Requires texlive-20230313-texmf, which is available at
|
||||
# https://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2023/texlive-20230313-texmf.tar.xz
|
||||
# download and extract this file as a .tar in this directory.
|
||||
[inputs."texlive"]
|
||||
source.tarball.path = "texlive-20230313-texmf.tar"
|
||||
source.tarball.hash = "ac1683d4abeb7fd534851ad7ff0ec891da7da4729603506efd0245259dcdcc67"
|
||||
source.tarball.root_dir = "texlive-20230313-texmf/texmf-dist"
|
||||
patch_dir = "patches/texlive"
|
||||
|
||||
ignore = [
|
||||
# I don't think tectonic has xindy support, ignore for now
|
||||
'''xindy/.*''',
|
||||
|
||||
# We may need this, but exclude for now.
|
||||
'''tex4ht/.*''',
|
||||
|
||||
# These require pLaTeX2e, tectonic uses XeTeX
|
||||
'''tex/uplatex/.*''',
|
||||
'''tex/uptex/.*''',
|
||||
|
||||
# Other odd tex formats & unnecessary files
|
||||
'''tex/cslatex/.*''',
|
||||
'''tex/csplain/.*''',
|
||||
'''tex/ptex/.*''',
|
||||
'''tex/platex/.*''',
|
||||
'''tex/lollipop/.*''',
|
||||
'''tex/context/.*''',
|
||||
'''context/.*''',
|
||||
'''texdoc/.*''',
|
||||
'''texdoctk/.*''',
|
||||
'''texconfig/.*''',
|
||||
'''scripts/.*''',
|
||||
'''dvips/.*''',
|
||||
'''asymptote/.*''',
|
||||
'''makeindex/.*''',
|
||||
'''luatex-cache/.*''',
|
||||
'''hb2gf/.*''',
|
||||
'''chktex/.*''',
|
||||
'''source/.*''',
|
||||
'''doc/.*''',
|
||||
'''tex/luatex/.*''',
|
||||
'''tex/lualatex/.*''',
|
||||
'''tex/lambda/.*''',
|
||||
'''omega/.*''',
|
||||
]
|
||||
|
||||
search_order = [
|
||||
"tex/{xelatex,latex,xetex,plain,generic}//",
|
||||
"bibtex/{bib,bst,csf}//",
|
||||
"web2c//",
|
||||
"fonts//",
|
||||
"biber//",
|
||||
"mft//",
|
||||
"dvips//",
|
||||
"makeindex//",
|
||||
"{web,cweb}//",
|
||||
"ttf2pk//",
|
||||
"dvipdfmx/",
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
\input xelatex.ini
|
|
@ -0,0 +1 @@
|
|||
\input plain \dump
|
|
@ -0,0 +1,24 @@
|
|||
tex/latex/fithesis/style/mu/fithesis-mu-base.sty
|
||||
131c131,138
|
||||
< \setmainfont[Ligatures=TeX]{TeX Gyre Pagella}
|
||||
---
|
||||
> \setmainfont{texgyrepagella}[
|
||||
> Ligatures = TeX,
|
||||
> Extension = .otf,
|
||||
> UprightFont = *-regular,
|
||||
> ItalicFont = *-italic,
|
||||
> BoldFont = *-bold,
|
||||
> BoldItalicFont = *-bolditalic,
|
||||
> ]
|
||||
136c143,151
|
||||
< \setsansfont[Ligatures=TeX,Scale=MatchLowercase]{TeX Gyre Heros}
|
||||
---
|
||||
> \setmainfont{texgyreheros}[
|
||||
> Ligatures = TeX,
|
||||
> Scale = MatchLowercase,
|
||||
> Extension = .otf,
|
||||
> UprightFont = *-regular,
|
||||
> ItalicFont = *-italic,
|
||||
> BoldFont = *-bold,
|
||||
> BoldItalicFont = *-bolditalic,
|
||||
> ]
|
|
@ -0,0 +1,5 @@
|
|||
tex/latex/fontawesome/fontawesome.sty
|
||||
45c45
|
||||
< \newfontfamily{\FA}{FontAwesome}
|
||||
---
|
||||
> \newfontfamily{\FA}{FontAwesome.otf}
|
|
@ -0,0 +1,32 @@
|
|||
tex/{latex,latex-dev}/base/latex.ltx
|
||||
7211,7237c7211,7212
|
||||
< \typeout{^^J! LaTeX Error: File `#1.#2' not found.^^J^^J%
|
||||
< Type X to quit or <RETURN> to proceed,^^J%
|
||||
< or enter new name. (Default extension: #2)^^J}%
|
||||
< \message{Enter file name: }%
|
||||
< {\endlinechar\m@ne
|
||||
< \global\read\m@ne to\@gtempa}%
|
||||
< \ifx\@gtempa\@empty
|
||||
< \let\@missingfile@area\@empty
|
||||
< \let\@missingfile@base\@empty
|
||||
< \def\@missingfile@ext{tex}%
|
||||
< \else
|
||||
< \def\reserved@b{\batchmode\read-1 to \reserved@a}%
|
||||
< \def\reserved@a{x}\ifx\reserved@a\@gtempa\reserved@b\fi
|
||||
< \def\reserved@a{X}\ifx\reserved@a\@gtempa\reserved@b\fi
|
||||
< \filename@parse\@gtempa
|
||||
< \edef\filename@ext{%
|
||||
< \ifx\filename@ext\relax#2\else\filename@ext\fi}%
|
||||
< \edef\reserved@a{%
|
||||
< \noexpand\IfFileExists
|
||||
< {\filename@area\filename@base.\filename@ext}%
|
||||
< {\def\noexpand\@missingfile@area{\filename@area}%
|
||||
< \def\noexpand\@missingfile@base{\filename@base}%
|
||||
< \def\noexpand\@missingfile@ext {\filename@ext}}%
|
||||
< {\noexpand\@missingfileerror
|
||||
< {\filename@area\filename@base}{\filename@ext}}}%
|
||||
< \reserved@a
|
||||
< \fi
|
||||
---
|
||||
> % Tectonic: no terminal input allowed, so this is always a fatal error.
|
||||
> \errmessage{! LaTeX Error: File `#1.#2' not found.}%
|
|
@ -0,0 +1,25 @@
|
|||
tex/latex/listings/listings.sty
|
||||
2057,2075c2057,2059
|
||||
< \typeout{^^J! Package Listings Error: File `#1(.#2)' not found.^^J%
|
||||
< ^^JType X to quit or <RETURN> to proceed,^^J%
|
||||
< or enter new name. (Default extension: #2)^^J}%
|
||||
< \message{Enter file name: }%
|
||||
< {\endlinechar\m@ne \global\read\m@ne to\@gtempa}%
|
||||
< \ifx\@gtempa\@empty \else
|
||||
< \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi
|
||||
< \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi
|
||||
< \filename@parse\@gtempa
|
||||
< \edef\filename@ext{%
|
||||
< \ifx\filename@ext\relax#2\else\filename@ext\fi}%
|
||||
< \edef\reserved@a{\noexpand\IfFileExists %
|
||||
< {\filename@area\filename@base.\filename@ext}%
|
||||
< {\noexpand\lst@InputListing %
|
||||
< {\filename@area\filename@base.\filename@ext}}%
|
||||
< {\noexpand\lst@MissingFileError
|
||||
< {\filename@area\filename@base}{\filename@ext}}}%
|
||||
< \expandafter\reserved@a %
|
||||
< \fi}
|
||||
---
|
||||
> % Tectonic: no terminal input allowed, so this is always a fatal error.
|
||||
> \errmessage{! Package Listings Error: File `#1(.#2)' not found.}%
|
||||
> }
|
|
@ -0,0 +1,63 @@
|
|||
# Tectonic Bundle Format V1 Specification
|
||||
|
||||
A single TTBv1 bundle may be used on the network or from a local filesystem. This bundle format contains two parts:
|
||||
- A 66-byte header, documented below
|
||||
- File data, a concatenated blob of gzipped files. One of these blobs is the bundle index.
|
||||
|
||||
Note that the extension for a tectonic bundle is `ttb`, regardless of its version. Also note that a bundle's hash depends on it's content. If we generate two bundles in different formats from one specification, the the resulting bundle hashes should be identical..
|
||||
|
||||
|
||||
### Header format
|
||||
A TTBv1 header consists of the following fields, in order.
|
||||
All numbers are stored with little-endian byte ordering.
|
||||
|
||||
- `14 bytes`: magic bytes. Always `tectonicbundle`, in any ttb version.
|
||||
- ` 4 bytes`: bundle version, a `u32`. In this case, always 1.
|
||||
- ` 8 bytes`: index location, a `u64`. This is the first byte of the bundle index file.
|
||||
- ` 4 bytes`: gzipped index length, a `u32`. This is the length the bundle index file.
|
||||
- ` 4 bytes`: true index length, a `u32`. This is the decompressed length of the bundle index file.
|
||||
- `32 bytes`: this bundle's hash.
|
||||
|
||||
|
||||
### Index
|
||||
Bundle contents are stored as a concatenated `gzip` blobs after the header. These are found using a special file called the Index, the location of which location is stored in the header. The index is generated from the "meta-files" that the file selector produces, namely `FILELIST` and `SEARCH`. These are included in the bundle for consistency, but shouldn't ever be used.
|
||||
|
||||
The index may be retrieved from a bundle by running `dd if=file.ttb ibs=1 skip=<start> count=<len> | gunzip`.
|
||||
|
||||
|
||||
The Index file comes in sections, each of which starts on a line marked with square braces. The following sections are currently used, all others are ignored.
|
||||
|
||||
- `[DEFAULTSEARCH]`: the default search order.
|
||||
- `[SEARCH:<name>]`: a search specification. Tectonic will search these paths for files, in this order. See the [bundle spec documentation](../../bundles/README.md).
|
||||
- `[FILELIST]`: a list of files in this bundle.
|
||||
- Each line contains the following: `<start_byte> <gzip_len> <real_len> <hash> <path>`
|
||||
- `<hash>` is either a sha256 hash, or `nohash` for certain special files.
|
||||
- `<start_byte>` and `<gzip_len>` are the location and length of files in the bundle.
|
||||
- `<real_len>` is the decompressed length of each file, used for efficient memory allocation.
|
||||
- `<path>` is the file's path. This is relative, and doesn't start with a slash. Also, this is intentionally last: paths may contain spaces (but not newlines!).
|
||||
|
||||
This index is generated by a script, so *very little error-checking is done inside Tectonic*. Keep the following in mind:
|
||||
- Empty lines should not exist
|
||||
- Any lines before a section specification are ignored
|
||||
- Invalid sections are ignored
|
||||
- Only the last line of `[DEFAULTSEARCH]` has any effect
|
||||
- We assume that the default `[SEARCH:<name>]` exists.
|
||||
|
||||
An example index is below.
|
||||
```
|
||||
[DEFAULTSEARCH]
|
||||
MAIN
|
||||
[SEARCH:MAIN]
|
||||
/
|
||||
/include//
|
||||
/texlive/tex/xelatex//
|
||||
/texlive/tex/latex//
|
||||
/texlive/tex/xetex//
|
||||
/texlive/tex/plain//
|
||||
[FILELIST]
|
||||
70 6065990 17331559 nohash FILELIST
|
||||
6066060 133 360 589b5c09a33c2655c76f9a6b9bbb6060674c896fbc5b4555af0e20c86f32ac13 SEARCH
|
||||
6066193 72 65 nohash SHA256SUM
|
||||
6066265 39 19 86d8d12cfdfbe74a81b9df7c5b38a766303a772d57e7cb0d228e1e7b9294cf34 include/tectonic/tectonic-format-latex.tex
|
||||
... many more lines ...
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
# Testing Bundles
|
||||
These are a work in progress, and may be broken.
|
||||
All tests are run through `test.sh` as follows: `./test.sh <path-to-ttb> <test set>`.
|
||||
|
||||
Tests require the following:
|
||||
- a `ttb` bundle (local or remote)
|
||||
- a recent installation of Tectonic
|
||||
|
||||
## Test Sets
|
||||
The following test sets are avaiable:
|
||||
- `files`, which tries to compile all files under `tests/files` and `tests/formats`
|
||||
- `classes`, which tries to compile a simple document using `tests/classes.list`
|
||||
|
||||
Note that most test files contain comments explaining the reason and expected outcome of the test.
|
||||
|
||||
|
||||
|
||||
## Test Output
|
||||
All test output ends up under `tests/build`
|
||||
|
||||
**Output for `files`:**
|
||||
- `files/logs`: log files for all builds (passed or failed)
|
||||
- `files/*.{pdf,fmt,etc}`: output files for each build
|
||||
|
||||
|
||||
**Output for `classes`**
|
||||
- `failed`: classes that failed to compile
|
||||
- `passed`: classes that complied without error
|
||||
- `logs`: log files for all compile jobs
|
|
@ -0,0 +1,628 @@
|
|||
BHCexam xfail
|
||||
BMSTU-IU8 xfail
|
||||
ConcProg ok
|
||||
FUpowerdot xfail
|
||||
IEEEconf ok
|
||||
IEEEtran ok
|
||||
IMTEKda xfail
|
||||
ReadableCV xfail
|
||||
RecipeBook ok
|
||||
SPhdThesis ok
|
||||
TOPletter xfail
|
||||
URbeamer xfail
|
||||
URletter xfail
|
||||
UoWthesis ok
|
||||
a0poster ok
|
||||
aalok xfail
|
||||
aastex ok
|
||||
aastex61 ok
|
||||
aastex62 ok
|
||||
aastex63 ok
|
||||
aastex631 ok
|
||||
abntex2 ok
|
||||
abstbook ok
|
||||
achemso ok,titleauth
|
||||
acmart ok
|
||||
acmconf xfail
|
||||
active-conf ok
|
||||
adfathesis ok
|
||||
afparticle ok,titleauth
|
||||
afthesis ok
|
||||
agecon ok
|
||||
aguplus xfail
|
||||
aiaa-tc ok
|
||||
ajae ok
|
||||
akklecture ok,titleauth
|
||||
akkscript ok
|
||||
akktecdoc ok
|
||||
akletter ok
|
||||
ametsoc ok
|
||||
amsart ok
|
||||
amsbook ok
|
||||
amsdtx ok
|
||||
amsldoc ok
|
||||
amsproc ok
|
||||
aomart ok
|
||||
apa ok
|
||||
apa6 xfail - looks unmaintained; uses known option to flushend package
|
||||
apa6e xfail
|
||||
apa7 ok
|
||||
apecon ok
|
||||
arabart ok
|
||||
arabbook ok
|
||||
arabic-book xfail
|
||||
arabrep ok
|
||||
arabrep1 xfail
|
||||
argetabelle ok
|
||||
article ok
|
||||
articleingud ok
|
||||
articoletteracdp ok
|
||||
artikel1 ok
|
||||
artikel2 ok
|
||||
artikel3 ok
|
||||
asaetr ok
|
||||
ascelike ok
|
||||
asmeconf xfail
|
||||
asmejour xfail - typo breaks build on XeTeX
|
||||
assignment ok
|
||||
aucklandthesis ok
|
||||
bangorcsthesis xfail
|
||||
bangorexam xfail
|
||||
bankstatement ok
|
||||
barticle xfail
|
||||
basque-book ok
|
||||
bbook xfail
|
||||
beamer ok
|
||||
beamer-rl xfail
|
||||
beamerswitch xfail
|
||||
beaulivre ok
|
||||
beilstein ok
|
||||
beletter ok
|
||||
bewerbung ok
|
||||
bfhbeamer xfail
|
||||
bfhpub xfail
|
||||
bfhsciposter xfail
|
||||
bfhthesis xfail
|
||||
bgteubner xfail
|
||||
bidimoderncv xfail
|
||||
bidipresentation ok
|
||||
biditufte-book ok
|
||||
biditufte-handout ok
|
||||
bitart xfail
|
||||
bitbook xfail
|
||||
bjfuthesis xfail
|
||||
bletter ok
|
||||
bmstu xfail
|
||||
boek ok
|
||||
boek3 ok
|
||||
book ok
|
||||
bookcover ok
|
||||
bookest ok
|
||||
bookshelf xfail
|
||||
br-lex ok
|
||||
brandeis-dissertation ok
|
||||
brandeis-problemset xfail
|
||||
brandeis-thesis xfail
|
||||
brief ok
|
||||
buctcover xfail
|
||||
buctthesis xfail
|
||||
businesscard-qrcode ok
|
||||
bxjsarticle ok
|
||||
bxjsbook ok
|
||||
bxjsreport ok
|
||||
bxjsslide ok
|
||||
caesar_book ok
|
||||
cas-dc xfail
|
||||
cas-sc xfail
|
||||
cascadilla xfail
|
||||
cassete ok
|
||||
cc xfail
|
||||
cd ok
|
||||
cd-cover ok
|
||||
cesenaexam xfail
|
||||
cheatsheet ok
|
||||
chletter ok
|
||||
cje xfail
|
||||
cnbwp xfail
|
||||
cnltx-doc xfail
|
||||
codedoc ok
|
||||
colorart ok
|
||||
colorbook ok
|
||||
combine xfail
|
||||
confproc xfail
|
||||
contracard ok
|
||||
cours ok
|
||||
courseoutline ok
|
||||
coursepaper ok
|
||||
cquthesis xfail
|
||||
csbulletin ok
|
||||
csbulobalka xfail
|
||||
csbulv1 xfail
|
||||
ctexart ok
|
||||
ctexbeamer ok
|
||||
ctexbook ok
|
||||
ctexrep ok
|
||||
ctxdoc ok
|
||||
curve ok
|
||||
cv4tw xfail
|
||||
cweb xfail
|
||||
dfgproposal xfail
|
||||
dfgreporting xfail
|
||||
dinbrief ok
|
||||
disser xfail
|
||||
dithesis xfail
|
||||
document-structure xfail
|
||||
droit-fr xfail
|
||||
dtk ok
|
||||
dvdcoll ok
|
||||
easybook ok
|
||||
ebsthesis ok
|
||||
ecca ok
|
||||
ecv xfail
|
||||
einfart ok
|
||||
ejpecp xfail
|
||||
elbioimp ok
|
||||
elegantbook ok
|
||||
elegantnote ok
|
||||
elegantpaper ok
|
||||
elpres ok
|
||||
elsarticle ok
|
||||
elteikthesis ok
|
||||
emisa xfail
|
||||
emulateapj ok
|
||||
erae ok
|
||||
erdc xfail
|
||||
eskd xfail
|
||||
eskdgraph xfail
|
||||
eskdtab xfail
|
||||
eskdtext xfail
|
||||
estcpmm ok
|
||||
etiketka ok
|
||||
euproposal xfail
|
||||
eureporting xfail
|
||||
europasscv xfail
|
||||
europecv ok
|
||||
europroc ok
|
||||
exam ok
|
||||
exam-n ok
|
||||
examdesign xfail
|
||||
exesheet ok
|
||||
extarticle ok
|
||||
extbook ok
|
||||
extletter ok
|
||||
extproc ok
|
||||
extreport ok
|
||||
facsimile ok
|
||||
factura xfail
|
||||
facture xfail
|
||||
fancyhandout ok
|
||||
fancyslides ok
|
||||
fbithesis xfail
|
||||
fcavtex ok
|
||||
fdudoc xfail
|
||||
fduthesis xfail
|
||||
fduthesis-en xfail
|
||||
fei xfail
|
||||
ffslides xfail
|
||||
fiche ok
|
||||
fithesis ok
|
||||
fithesis2 ok
|
||||
fithesis3 ok
|
||||
fithesis4 ok
|
||||
flacards ok
|
||||
flashcard xfail
|
||||
flashcards xfail
|
||||
frletter ok
|
||||
fsbispit xfail
|
||||
g-brief ok
|
||||
g-brief2 ok
|
||||
gaceta ok
|
||||
gammas xfail
|
||||
geradwp ok
|
||||
gmdocc ok
|
||||
gost732 xfail
|
||||
gradstudentresume xfail
|
||||
grant xfail
|
||||
grant-afosr xfail
|
||||
grant-aro xfail
|
||||
grant-darpa xfail
|
||||
grant-doe xfail
|
||||
grant-nih xfail
|
||||
grant-nrl xfail
|
||||
grant-nsf xfail
|
||||
grant-onr xfail
|
||||
graphpaper ok
|
||||
gridslides ok
|
||||
gsemthesis ok
|
||||
guitartabs ok
|
||||
gzt xfail
|
||||
gztarticle ok
|
||||
h2020proposal ok
|
||||
harnon-cv xfail
|
||||
hausarbeit-jura xfail
|
||||
hcart xfail
|
||||
hcletter xfail
|
||||
hcreport xfail
|
||||
hcslides xfail
|
||||
hecthese ok
|
||||
hepthesis ok
|
||||
hgbarticle xfail
|
||||
hgbreport xfail
|
||||
hgbthesis xfail
|
||||
hitec ok,titleauth
|
||||
hithesis xfail
|
||||
hitreport ok
|
||||
hitszthesis xfail
|
||||
hletter ok
|
||||
hpsdiss xfail
|
||||
hu-berlin-letter xfail
|
||||
huawei ok
|
||||
hustthesis xfail
|
||||
hwexam xfail
|
||||
iagproc ok
|
||||
icsv ok
|
||||
idcc xfail
|
||||
ijdc-v14 xfail
|
||||
ijdc-v9 ok
|
||||
ijmart ok
|
||||
ijsra xfail
|
||||
image-gallery ok
|
||||
imsproc ok
|
||||
inkpaper xfail
|
||||
invoice-class ok
|
||||
iodhbwm ok
|
||||
iscram ok
|
||||
isodoc xfail
|
||||
isov2 ok
|
||||
itaxpf ok
|
||||
iwhdp xfail
|
||||
jacow xfail
|
||||
jarticle xfail
|
||||
jbook xfail
|
||||
jlreq xfail
|
||||
jltxdoc xfail
|
||||
jmlr ok
|
||||
jmlrbook xfail
|
||||
jnuexam ok
|
||||
journal ok
|
||||
jpsj2 ok
|
||||
jreport xfail
|
||||
jrurstud ok
|
||||
jsarticle xfail
|
||||
jsbook xfail
|
||||
jspf xfail
|
||||
jsreport xfail
|
||||
jura ok
|
||||
jurabook ok
|
||||
juraovw ok
|
||||
juraurtl ok
|
||||
kdgcoursetext ok,titleauth
|
||||
kdgmasterthesis ok,titleauth
|
||||
kdpcover ok
|
||||
kerntest xfail
|
||||
kiyou xfail
|
||||
kluwer ok
|
||||
knittingpattern ok
|
||||
komacv ok
|
||||
ksp-thesis xfail
|
||||
l3doc ok
|
||||
labbook ok
|
||||
langscibook xfail
|
||||
leadsheet ok
|
||||
leaflet ok
|
||||
lebhart ok
|
||||
lectures xfail
|
||||
legislation xfail
|
||||
letgut xfail
|
||||
letter ok
|
||||
letteracdp ok
|
||||
lettre ok
|
||||
limap ok
|
||||
limecv xfail
|
||||
lion-msc xfail
|
||||
llncs ok
|
||||
lni ok,titleauth
|
||||
lps ok
|
||||
lt3graph-packagedoc xfail
|
||||
ltjarticle xfail
|
||||
ltjbook xfail
|
||||
ltjltxdoc xfail
|
||||
ltjreport xfail
|
||||
ltjsarticle xfail
|
||||
ltjsbook xfail
|
||||
ltjskiyou xfail
|
||||
ltjspf xfail
|
||||
ltjsreport xfail
|
||||
ltjtarticle xfail
|
||||
ltjtbook xfail
|
||||
ltjtreport xfail
|
||||
ltnews ok
|
||||
ltugboat ok
|
||||
ltugproc ok
|
||||
ltxdoc ok
|
||||
ltxdockit ok
|
||||
ltxguide ok
|
||||
ltxguidex ok
|
||||
ltxmdf xfail
|
||||
matapli xfail
|
||||
matc3mem ok
|
||||
mcmthesis ok
|
||||
medstarbeamer xfail
|
||||
meetingmins ok
|
||||
memoir ok
|
||||
mensa-tex ok
|
||||
mentis xfail
|
||||
metanorma ok
|
||||
milog ok
|
||||
minimal ok
|
||||
minimart ok
|
||||
minimbook ok
|
||||
mla ok
|
||||
mluexercise xfail
|
||||
mnras ok
|
||||
moderncv xfail
|
||||
modernposter ok
|
||||
movie ok
|
||||
msu-thesis ok
|
||||
mucproc xfail
|
||||
mugsthesis ok
|
||||
muling ok
|
||||
musuos ok
|
||||
muthesis ok
|
||||
mwart ok
|
||||
mwbk ok
|
||||
mwrep ok
|
||||
my-thesis ok
|
||||
mycv ok
|
||||
myletter ok
|
||||
mynsfc ok
|
||||
nanicolle xfail
|
||||
nature ok
|
||||
ncc ok
|
||||
nccproc ok
|
||||
nddiss2e xfail
|
||||
ndsu-thesis ok
|
||||
newlfm xfail
|
||||
nih ok
|
||||
nihbiosketch xfail
|
||||
njf ok
|
||||
njurepo xfail
|
||||
njustthesis xfail
|
||||
njuthesis ok
|
||||
nlctdoc ok
|
||||
nostarch xfail
|
||||
notesslides ok
|
||||
novel xfail
|
||||
nrc1 xfail
|
||||
nrc2 xfail
|
||||
nwafuthesis xfail
|
||||
nwejm xfail
|
||||
nwejmart xfail - assumes font "Latin Modern Mono" is available
|
||||
oblivoir ok
|
||||
oblivoir-utf xfail
|
||||
oblivoir-xl xfail
|
||||
octavo ok
|
||||
oegatb xfail
|
||||
onrannual ok
|
||||
oup-authoring-template ok
|
||||
paper ok
|
||||
papertex xfail
|
||||
pbsheet xfail
|
||||
pdfArticle xfail
|
||||
pecha xfail
|
||||
petiteannonce ok
|
||||
phfextendedabstract ok
|
||||
philosophersimprint ok
|
||||
pittetd ok
|
||||
pkuthss xfail
|
||||
plari ok
|
||||
play ok
|
||||
plnews xfail
|
||||
pocoec ok
|
||||
postcards xfail
|
||||
powerdot xfail
|
||||
powersem xfail
|
||||
ppr-prv xfail
|
||||
pracjourn ok
|
||||
pressrelease ok
|
||||
proc ok
|
||||
proposal xfail
|
||||
prosper xfail
|
||||
protocol ok
|
||||
prtec ok
|
||||
ptptex ok
|
||||
qcm ok
|
||||
quantumarticle xfail
|
||||
qyxf-book xfail
|
||||
rapport1 ok
|
||||
rapport3 ok
|
||||
rbt-mathnotes xfail
|
||||
rbt-mathnotes-formula-sheet xfail
|
||||
rbt-mathnotes-hw xfail
|
||||
recipe ok
|
||||
recipecard xfail
|
||||
refart ok
|
||||
refrep ok
|
||||
regstud ok
|
||||
report ok
|
||||
reporting xfail
|
||||
resphilosophica ok
|
||||
resumecls ok
|
||||
revtex4 ok
|
||||
revtex4-1 ok
|
||||
revtex4-2 ok
|
||||
rtklage xfail
|
||||
ryersonSGSThesis xfail
|
||||
ryethesis xfail
|
||||
sageep ok
|
||||
sapthesis ok
|
||||
schuleab ok
|
||||
schulein ok
|
||||
schuleit ok
|
||||
schulekl ok
|
||||
schuleub xfail
|
||||
schuleue ok
|
||||
schullsg ok
|
||||
schullzk ok
|
||||
schulma-ab ok
|
||||
schulma-gutachten ok
|
||||
schulma-klausur xfail
|
||||
schulma-komp ok
|
||||
schulma-mdlprf ok
|
||||
schulma-praes ok
|
||||
sciposter ok
|
||||
scrartcl ok
|
||||
scrarticle ok
|
||||
scrbook ok
|
||||
scrdoc ok
|
||||
screenplay ok
|
||||
scrguide xfail
|
||||
scrjrnl xfail
|
||||
scrletter ok
|
||||
scrlttr2 ok
|
||||
scrreport ok
|
||||
scrreprt ok
|
||||
sdapsclassic xfail
|
||||
sduthesis ok
|
||||
seminar xfail
|
||||
semproc ok
|
||||
sesamanuel xfail
|
||||
seu-ml-assign xfail
|
||||
seuthesix xfail
|
||||
sffms ok,titleauth
|
||||
shtthesis xfail
|
||||
sibjnm xfail
|
||||
sides ok
|
||||
simplecv ok
|
||||
simpleresumecv xfail
|
||||
simplethesisdissertation xfail
|
||||
simplivre ok
|
||||
simurgh-doc xfail
|
||||
skbarticle ok
|
||||
skbbeamer ok
|
||||
skbbook ok
|
||||
skblncsbeamer xfail
|
||||
skblncsppt ok
|
||||
skbmoderncv xfail
|
||||
skdoc xfail
|
||||
skeyval-testclass xfail
|
||||
skrapport xfail
|
||||
slides ok
|
||||
smfart ok
|
||||
smfbook ok
|
||||
source2edoc ok
|
||||
spie ok
|
||||
sr-vorl ok
|
||||
sslides ok
|
||||
stage ok
|
||||
standalone ok
|
||||
stex xfail
|
||||
subfiles xfail
|
||||
suftesi xfail
|
||||
sugconf titleauth,xfail - uses inputenc
|
||||
tabriz-thesis ok
|
||||
talk ok
|
||||
tarticle xfail
|
||||
tbook xfail
|
||||
tcldoc ok
|
||||
tclldoc ok
|
||||
technionThesis xfail
|
||||
thesis-ekf ok
|
||||
thesis-gwu xfail
|
||||
thesis-qom xfail
|
||||
third-rep xfail
|
||||
thuthesis ok
|
||||
tikz-kalender ok
|
||||
tikzposter ok
|
||||
tlc-article ok,titleauth
|
||||
toptesi ok
|
||||
treport xfail
|
||||
tudabeamer xfail
|
||||
tudaexercise ok
|
||||
tudaleaflet ok
|
||||
tudaletter xfail
|
||||
tudaposter xfail
|
||||
tudapub xfail
|
||||
tudasciposter ok
|
||||
tudscrartcl ok
|
||||
tudscrbook ok
|
||||
tudscrdoc ok
|
||||
tudscrmanual xfail
|
||||
tudscrposter ok
|
||||
tudscrreprt ok
|
||||
tufte-book ok
|
||||
tufte-handout ok
|
||||
tui xfail
|
||||
turabian xfail
|
||||
turabian-researchpaper ok
|
||||
turabian-thesis ok
|
||||
ua-thesis ok
|
||||
uafthesis ok
|
||||
uantwerpenbamathesis ok
|
||||
uantwerpencoursetext ok
|
||||
uantwerpenexam ok
|
||||
uantwerpenletter ok
|
||||
uantwerpenphdthesis ok
|
||||
uantwerpenreport ok
|
||||
ucalgmthesis ok
|
||||
ucbthesis ok
|
||||
ucdavisthesis ok
|
||||
ucsmonograph ok
|
||||
ucthesis ok
|
||||
udesoftec xfail
|
||||
uebungsblatt xfail
|
||||
uestcthesis xfail
|
||||
uhhassignment ok
|
||||
uiucredborder ok
|
||||
uiucthesis ok
|
||||
ujarticle xfail
|
||||
ujbook xfail
|
||||
ujreport xfail
|
||||
ulthese xfail
|
||||
umich-thesis ok
|
||||
umthesis ok
|
||||
unam-thesis xfail
|
||||
unbtex ok
|
||||
unifith ok
|
||||
unitn-bimrep xfail
|
||||
univie-ling-expose ok
|
||||
univie-ling-paper ok
|
||||
univie-ling-thesis ok
|
||||
univie-ling-wlg xfail
|
||||
unizgklasa ok
|
||||
uothesis ok
|
||||
upmethodology-document xfail
|
||||
upmgr ok
|
||||
uspatent ok
|
||||
usthesis xfail
|
||||
ut-thesis ok
|
||||
utarticle xfail
|
||||
utbook xfail
|
||||
utexasthesis ok
|
||||
utreport xfail
|
||||
uwa-pcf xfail
|
||||
uwa-pif xfail
|
||||
uwmslide ok
|
||||
uwthesis ok
|
||||
verifica ok
|
||||
wallcalendar xfail
|
||||
webquiz ok
|
||||
willowtreebook xfail
|
||||
withargs-packagedoc xfail
|
||||
wkmgr ok
|
||||
worlddev ok
|
||||
wsemclassic xfail
|
||||
xduthesis xfail
|
||||
xebaposter xfail
|
||||
xepersian-magazine ok
|
||||
xmuthesis xfail
|
||||
xoblivoir ok
|
||||
xsim-manual xfail
|
||||
yaletter xfail
|
||||
yathesis ok
|
||||
yazd-thesis ok
|
||||
yb-book xfail
|
||||
ycbook ok
|
||||
ydoc xfail
|
||||
york-thesis ok
|
||||
zbMATH ok
|
|
@ -0,0 +1,94 @@
|
|||
\documentclass[12pt]{article}
|
||||
\usepackage[inline]{asymptote}
|
||||
|
||||
% This test compiles without error, but
|
||||
% the output pdf is missing graphics.
|
||||
|
||||
|
||||
\title{2D Graphics with Asymptote}
|
||||
\author{The Asymptote Project}
|
||||
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\begin{asydef}
|
||||
//
|
||||
// Global Asymptote definitions can be put here.
|
||||
//
|
||||
usepackage("bm");
|
||||
texpreamble("\def\V#1{\bm{#1}}");
|
||||
\end{asydef}
|
||||
|
||||
Here is a venn diagram produced with Asymptote, drawn to width 4cm:
|
||||
|
||||
\def\A{A}
|
||||
\def\B{\V{B}}
|
||||
|
||||
\begin{center}
|
||||
\begin{asy}
|
||||
size(4cm,0);
|
||||
pen colour1=red;
|
||||
pen colour2=green;
|
||||
|
||||
pair z0=(0,0);
|
||||
pair z1=(-1,0);
|
||||
pair z2=(1,0);
|
||||
real r=1.5;
|
||||
path c1=circle(z1,r);
|
||||
path c2=circle(z2,r);
|
||||
fill(c1,colour1);
|
||||
fill(c2,colour2);
|
||||
|
||||
picture intersection=new picture;
|
||||
fill(intersection,c1,colour1+colour2);
|
||||
clip(intersection,c2);
|
||||
|
||||
add(intersection);
|
||||
|
||||
draw(c1);
|
||||
draw(c2);
|
||||
|
||||
//draw("$\A$",box,z1); // Requires [inline] package option.
|
||||
//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option.
|
||||
draw("$A$",box,z1);
|
||||
draw("$\V{B}$",box,z2);
|
||||
|
||||
pair z=(0,-2);
|
||||
real m=3;
|
||||
margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
|
||||
|
||||
draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
|
||||
draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
|
||||
draw(z--z1,Arrow,Margin(0,m));
|
||||
draw(z--z2,Arrow,Margin(0,m));
|
||||
|
||||
shipout(bbox(0.25cm));
|
||||
\end{asy}
|
||||
\end{center}
|
||||
|
||||
Here are some graphs. The figure is scaled to line width.
|
||||
\begin{center}
|
||||
\begin{asy}[width=\the\linewidth,inline=true]
|
||||
pair z0=(0,0);
|
||||
pair z1=(2,0);
|
||||
pair z2=(5,0);
|
||||
pair zf=z1+0.75*(z2-z1);
|
||||
|
||||
draw(z1--z2);
|
||||
dot(z1,red+0.15cm);
|
||||
dot(z2,darkgreen+0.3cm);
|
||||
label("$m$",z1,1.2N,red);
|
||||
label("$M$",z2,1.5N,darkgreen);
|
||||
label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue);
|
||||
|
||||
pair s=-0.2*I;
|
||||
draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
|
||||
s=-0.5*I;
|
||||
draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
|
||||
s=-0.95*I;
|
||||
draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
|
||||
\end{asy}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,14 @@
|
|||
\documentclass{article}
|
||||
|
||||
\usepackage{chessfss}
|
||||
\usepackage{chessboard}
|
||||
\usepackage{xskak}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\newchessgame
|
||||
\chessboard[normalboard, showmover=false]
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,10 @@
|
|||
\documentclass{article}
|
||||
\usepackage{fontawesome}
|
||||
|
||||
% Fontawesome was patched to fix font path.
|
||||
% It should now look for fonts in the bundle
|
||||
% rather than system font dirs.
|
||||
|
||||
\begin{document}
|
||||
\faStar
|
||||
\end{document}
|
|
@ -0,0 +1,44 @@
|
|||
\documentclass[
|
||||
digital,
|
||||
twoside,
|
||||
nolof,
|
||||
nolot
|
||||
]{fithesis4}
|
||||
\usepackage[main=english]{babel}
|
||||
|
||||
% The fithesis document class uses tex paths in many odd ways:
|
||||
% - it provides many files with the same name
|
||||
% - it loads these files, depending on configuration, with a partial path
|
||||
%
|
||||
% This behavior makes fithesis a good test case for
|
||||
% Tectonic's file search algorithm.
|
||||
|
||||
|
||||
\thesissetup{
|
||||
date = \the\year/\the\month/\the\day,
|
||||
university = mu,
|
||||
faculty = sci,
|
||||
type = bc,
|
||||
programme = NA,
|
||||
field = Sport Management,
|
||||
department = Department of Social Sciences and Sport Management,
|
||||
author = Jane Doe,
|
||||
gender = f,
|
||||
advisor = {Prof. RNDr. John Smith, CSc.},
|
||||
title = The use of LaTeX for the Typesetting
|
||||
of Sports Tables,
|
||||
TeXtitle = The use of \LaTeX\ for the Typesetting
|
||||
of Sports Tables,
|
||||
keywords = {keyword1, keywords2, ...},
|
||||
TeXkeywords = {keyword1, keywords2, \ldots},
|
||||
abstract = {%
|
||||
This is the abstract of my thesis, which can
|
||||
span multiple paragraphs.
|
||||
}
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
test
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,19 @@
|
|||
\documentclass{article}
|
||||
|
||||
\usepackage{fontspec}
|
||||
\setmainfont{TeX Gyre Pagella}
|
||||
|
||||
% Try to load a font by name.
|
||||
% At the moment, this searches the system font cache,
|
||||
% and thus usually fails.
|
||||
%
|
||||
% Eventually we'll implement support for that in Tectonic:
|
||||
% we should check the bundle for ALL fonts, even those loaded
|
||||
% by name.
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section*{Introduction}
|
||||
This is Introduction
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,20 @@
|
|||
\documentclass{article}
|
||||
\usepackage{markdown}
|
||||
|
||||
% The markdown package requires shell escapes,
|
||||
% which are currently disabled.
|
||||
% We expect this test to fail, for now.
|
||||
|
||||
\begin{document}
|
||||
\begin{markdown}
|
||||
# Grocery list
|
||||
|
||||
## Food
|
||||
- baked beans
|
||||
- spaghetti
|
||||
|
||||
## Stationery
|
||||
- writing pad
|
||||
- pencils
|
||||
\end{markdown}
|
||||
\end{document}
|
|
@ -0,0 +1,11 @@
|
|||
\documentclass{report}
|
||||
\usepackage{pgfornament}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
Below is a test ornament.\linebreak
|
||||
\pgfornament[scale=0.125]{3}
|
||||
\end{center}
|
||||
|
||||
\end{document}
|
|
@ -0,0 +1,7 @@
|
|||
\documentclass[a4paper,12pt]{article}
|
||||
\usepackage{polyglossia}
|
||||
\setmainlanguage[variant=brazilian]{portuguese}
|
||||
|
||||
\begin{document}
|
||||
Test
|
||||
\end{document}
|
|
@ -0,0 +1 @@
|
|||
\input xelatex.ini
|
|
@ -0,0 +1 @@
|
|||
\input plain \dump
|
|
@ -0,0 +1,302 @@
|
|||
#! /usr/bin/env python3
|
||||
# -*- mode: python; coding: utf-8 -*-
|
||||
# Copyright 2020-2021 the Tectonic Project.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
"""
|
||||
Test builds using some of the LaTeX package (style) files provided in a bundle.
|
||||
|
||||
There are thousands of these (about 5000 as of TeXLive 2020), so we use a
|
||||
reproducible-random scheme to skip most of them to keep the testing time
|
||||
reasonable. In particular:
|
||||
|
||||
- I did an initial run over all of the packages on the TeXLive 2020 bundle when
|
||||
setting this all up. All of the packages that failed were marked with a "skip"
|
||||
tag. These are always skipped.
|
||||
|
||||
- All of the packages were assigned a randomly-generated number between 0 and 99
|
||||
(inclusive), using a `rand=` key in the listing file. Of the remaining
|
||||
non-"skip" packages, only a fraction of them are tested, using the random key
|
||||
to select them. This program takes a `-S` option to specify the percentage of
|
||||
packages to test, and a `-K` option to specify which random subset to
|
||||
investigate. Packages where `(randkey + K) % 100 >= S` are skipped.
|
||||
|
||||
- Packages without a `rand=` setting are always tested.
|
||||
|
||||
- The default `-S` setting is 5%, which tests about 150 packages and takes about
|
||||
7 minutes to run. The default `-K` setting is random.
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
import random
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from test_utils import *
|
||||
|
||||
# We use percent formatting since all the TeX braces would be super annoying to
|
||||
# escape in str.format() formatting.
|
||||
DOC_CLASS_TEMPLATE = r"\documentclass{%(class)s}"
|
||||
PACKAGE_TEMPLATE = r"\usepackage{%(package)s}"
|
||||
|
||||
DOCUMENT_BODY = r"""\begin{document}
|
||||
Hello, world.
|
||||
\end{document}"""
|
||||
|
||||
|
||||
def entrypoint(argv):
|
||||
settings = make_arg_parser().parse_args(argv[1:])
|
||||
bundle = Bundle.open_with_inferred_state(settings.bundle_dir)
|
||||
|
||||
packagedir = bundle.test_path("packages")
|
||||
n_errors = 0
|
||||
n_surprises = 0
|
||||
n_tested = 0
|
||||
n_skipped = 0
|
||||
n_missing = 0
|
||||
n_removed = 0
|
||||
n_xfail = 0
|
||||
|
||||
# Random sampling setup
|
||||
|
||||
if settings.sample_key is None:
|
||||
settings.sample_key = random.randint(0, 99)
|
||||
|
||||
if settings.update:
|
||||
print("note: update mode engaged - will rewrite packages.txt")
|
||||
print()
|
||||
|
||||
# Load the packages from the bundle
|
||||
|
||||
bundle_packages = set()
|
||||
|
||||
with open(bundle.listing_path()) as flist:
|
||||
for line in flist:
|
||||
base = line.strip()
|
||||
if base.endswith(".sty"):
|
||||
bundle_packages.add(base[:-4])
|
||||
|
||||
# Load the stored information
|
||||
|
||||
ref_packages = {}
|
||||
packages_path = bundle.path("packages.txt")
|
||||
|
||||
with open(packages_path) as fref:
|
||||
for line in fref:
|
||||
bits = line.split()
|
||||
classname = bits[0]
|
||||
info = {}
|
||||
|
||||
info["tags"] = set(bits[1].split(","))
|
||||
|
||||
for bit in bits[2:]:
|
||||
if bit.startswith("rand="):
|
||||
info["randkey"] = int(bit[5:])
|
||||
else:
|
||||
die(f"unexpected metadata item {bit!r} in packages.txt")
|
||||
|
||||
ref_packages[classname] = info
|
||||
|
||||
# Cross-check the two lists
|
||||
|
||||
for p in bundle_packages:
|
||||
if p not in ref_packages:
|
||||
# `just_added` enables us to make sure to test new packages in
|
||||
# update mode
|
||||
print(f"MISSING {p} - not in packages.txt")
|
||||
ref_packages[p] = {
|
||||
"tags": set(["ok"]),
|
||||
"randkey": random.randint(0, 99),
|
||||
"just_added": settings.update,
|
||||
}
|
||||
|
||||
if not settings.update:
|
||||
n_missing += 1
|
||||
n_errors += 1
|
||||
|
||||
refkeys = list(ref_packages.keys())
|
||||
|
||||
for p in refkeys:
|
||||
if p not in bundle_packages:
|
||||
print(f"REMOVED {p} - in packages.txt but not bundle")
|
||||
del ref_packages[p]
|
||||
|
||||
if not settings.update:
|
||||
n_removed += 1
|
||||
n_errors += 1
|
||||
|
||||
if n_missing + n_removed > 0:
|
||||
print("NOTE: use --update to rebuild packages.txt if needed")
|
||||
|
||||
# Sampling setup.
|
||||
|
||||
if settings.sample_percentage is None:
|
||||
TARGET_N_PACKAGES = 100
|
||||
settings.sample_percentage = max(
|
||||
100 * TARGET_N_PACKAGES // len(ref_packages), 1
|
||||
)
|
||||
n_eff = settings.sample_percentage * len(ref_packages) // 100
|
||||
print(
|
||||
f"note: targeting about {n_eff} randomized test cases ({settings.sample_percentage}% of corpus; actual number will vary)"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"note: sampling {settings.sample_percentage}% of the randomized test cases"
|
||||
)
|
||||
|
||||
print(
|
||||
f"note: sample key is {settings.sample_key}; use argument `-K {settings.sample_key}` to reproduce this run`"
|
||||
)
|
||||
|
||||
# Run the tests
|
||||
|
||||
refkeys = sorted(ref_packages.keys())
|
||||
|
||||
for pkg in refkeys:
|
||||
info = ref_packages[pkg]
|
||||
tags = info["tags"]
|
||||
|
||||
if info.get("just_added", False):
|
||||
random_skipped = False
|
||||
elif "randkey" in info:
|
||||
effkey = (info["randkey"] + settings.sample_key) % 100
|
||||
random_skipped = effkey >= settings.sample_percentage
|
||||
else:
|
||||
random_skipped = False
|
||||
|
||||
if "skip" in tags or random_skipped:
|
||||
n_skipped += 1
|
||||
continue
|
||||
|
||||
print(pkg, "... ", end="")
|
||||
sys.stdout.flush()
|
||||
n_tested += 1
|
||||
|
||||
thisdir = os.path.join(packagedir, pkg)
|
||||
os.makedirs(thisdir, exist_ok=True)
|
||||
|
||||
texpath = os.path.join(thisdir, "index.tex")
|
||||
|
||||
params = {
|
||||
"class": "article",
|
||||
"package": pkg,
|
||||
}
|
||||
|
||||
with open(texpath, "wt") as f:
|
||||
print(DOC_CLASS_TEMPLATE % params, file=f)
|
||||
print(PACKAGE_TEMPLATE % params, file=f)
|
||||
print(DOCUMENT_BODY, file=f)
|
||||
|
||||
with open(os.path.join(thisdir, "log.txt"), "wb") as log:
|
||||
result = subprocess.call(
|
||||
[TECTONIC_PROGRAM, "-p", "-b", bundle.zip_path(), texpath],
|
||||
shell=False,
|
||||
stdout=log,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
|
||||
if result == 0:
|
||||
if "ok" in tags:
|
||||
print("pass", flush=True)
|
||||
else:
|
||||
# This test succeeded even though we didn't expect it to.
|
||||
# Not a bad thing, but worth noting!
|
||||
print("pass (unexpected)", flush=True)
|
||||
n_surprises += 1
|
||||
|
||||
try:
|
||||
tags.remove("xfail")
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
tags.add("ok")
|
||||
else:
|
||||
if "xfail" in tags:
|
||||
print("xfail", flush=True)
|
||||
n_xfail += 1
|
||||
else:
|
||||
# This test failed unexpectedly :-(
|
||||
print("FAIL", flush=True)
|
||||
n_errors += 1
|
||||
|
||||
if settings.update:
|
||||
try:
|
||||
tags.remove("ok")
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
tags.add("xfail")
|
||||
|
||||
print()
|
||||
print("Summary:")
|
||||
print(f"- Tested {n_tested} packages")
|
||||
if n_skipped:
|
||||
print(f"- {n_skipped} cases skipped")
|
||||
if n_missing:
|
||||
print(f"- {n_missing} packages missing from packages.txt")
|
||||
if n_removed:
|
||||
print(f"- {n_removed} packages in packages.txt removed from bundle")
|
||||
if n_xfail:
|
||||
print(f"- {n_xfail} expected failures")
|
||||
if n_surprises:
|
||||
print(f"- {n_surprises} surprise passes")
|
||||
if n_errors:
|
||||
print(
|
||||
f"- {n_errors} total errors: test failed (outputs stored in {packagedir})"
|
||||
)
|
||||
else:
|
||||
print(f"- no errors: test passed (outputs stored in {packagedir})")
|
||||
|
||||
# Update listing if needed
|
||||
|
||||
if settings.update:
|
||||
with open(packages_path, "wt") as f:
|
||||
for pkg in refkeys:
|
||||
info = ref_packages[pkg]
|
||||
tag_text = ",".join(sorted(info["tags"]))
|
||||
|
||||
randkey = info.get("randkey")
|
||||
if randkey is None:
|
||||
rest = ""
|
||||
else:
|
||||
rest = f" rand={randkey}"
|
||||
|
||||
print(pkg, " ", tag_text, rest, sep="", file=f)
|
||||
|
||||
# All done!
|
||||
|
||||
return 1 if n_errors and not settings.update else 0
|
||||
|
||||
|
||||
def make_arg_parser():
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument(
|
||||
"--update",
|
||||
action="store_true",
|
||||
help="Update mode: sync packages.txt to bundle; may wish to use `-S 100` too",
|
||||
)
|
||||
p.add_argument(
|
||||
"-S",
|
||||
"--samp-pct",
|
||||
dest="sample_percentage",
|
||||
type=int,
|
||||
help="The percentage of test cases to sample",
|
||||
)
|
||||
p.add_argument(
|
||||
"-K",
|
||||
"--samp-key",
|
||||
dest="sample_key",
|
||||
type=int,
|
||||
help='The "key" determining which random subset of cases are sampled',
|
||||
)
|
||||
p.add_argument(
|
||||
"bundle_dir",
|
||||
help="The directory of the bundle specification",
|
||||
)
|
||||
return p
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(entrypoint(sys.argv))
|
|
@ -0,0 +1,212 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
this_dir="$(pwd)"
|
||||
|
||||
test_dir="${this_dir}"
|
||||
|
||||
bundle_path="$(realpath "${1}")"
|
||||
output_dir="${test_dir}/build"
|
||||
|
||||
rm -drf "${output_dir}"
|
||||
mkdir -p "${output_dir}"
|
||||
|
||||
|
||||
function relative() {
|
||||
echo "./$(realpath --relative-to="${this_dir}" "${1}")"
|
||||
}
|
||||
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
|
||||
function test_files() {
|
||||
|
||||
rm -drf "${output_dir}/files"
|
||||
mkdir -p "${output_dir}/files"
|
||||
mkdir -p "${output_dir}/files/logs"
|
||||
|
||||
|
||||
|
||||
for f in "${test_dir}/files"/*; do
|
||||
echo -n "Testing file $(relative "${f}")..."
|
||||
|
||||
tectonic \
|
||||
--chatter minimal \
|
||||
--outdir "${output_dir}/files" \
|
||||
--bundle "${bundle_path}" \
|
||||
"${f}" \
|
||||
&> "${output_dir}/files/logs/$(basename "${f}").log"
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
echo -en "\r${GREEN}PASS${NC}"
|
||||
else
|
||||
echo -en "\r${RED}FAIL${NC}"
|
||||
fi
|
||||
echo " Tested file $(relative "${f}")"
|
||||
done
|
||||
|
||||
|
||||
for f in "${test_dir}/formats"/*; do
|
||||
echo -n "Testing format $(relative "${f}")..."
|
||||
|
||||
tectonic \
|
||||
--chatter minimal \
|
||||
--outdir "${output_dir}/files" \
|
||||
-p --outfmt "fmt" \
|
||||
--bundle "${bundle_path}" \
|
||||
"${f}" \
|
||||
&> "${output_dir}/files/logs/$(basename "${f}").log"
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
echo -en "\r${GREEN}PASS${NC}"
|
||||
else
|
||||
echo -en "\r${RED}FAIL${NC}"
|
||||
fi
|
||||
echo " Tested format $(relative "${f}")"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
function test_class_single() {
|
||||
local class="${1}"
|
||||
local flags="${2}"
|
||||
|
||||
mkdir -p "${output_dir}/classes/logs/failed"
|
||||
mkdir -p "${output_dir}/classes/logs/passed"
|
||||
local target="$(mktemp --tmpdir="${output_dir}/classes" "tmp.XXXX")"
|
||||
|
||||
(
|
||||
echo "\documentclass{${class}}"
|
||||
echo ""
|
||||
|
||||
if [[ $flags =~ "titleauth" ]]; then
|
||||
echo "title{Test Title}"
|
||||
echo "\author{An Author}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "\begin{document}"
|
||||
echo "Hello, world"
|
||||
echo "\end{document}"
|
||||
) > "${target}"
|
||||
|
||||
|
||||
tectonic \
|
||||
--chatter minimal \
|
||||
--outdir "${output_dir}/classes" \
|
||||
--bundle "${bundle_path}" \
|
||||
"${target}" \
|
||||
&> "${output_dir}/classes/logs/${class}.log"
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
echo "$class" >> "${output_dir}/classes/passed"
|
||||
mv "${output_dir}/classes/logs/${class}.log" "${output_dir}/classes/logs/passed"
|
||||
echo 0
|
||||
else
|
||||
echo "$class" >> "${output_dir}/classes/failed"
|
||||
mv "${output_dir}/classes/logs/${class}.log" "${output_dir}/classes/logs/failed"
|
||||
echo 1
|
||||
fi
|
||||
|
||||
rm "${target}"
|
||||
}
|
||||
|
||||
|
||||
function test_classes() {
|
||||
rm -drf "${output_dir}/classes"
|
||||
mkdir -p "${output_dir}/classes"
|
||||
|
||||
local fails=0
|
||||
local passes=0
|
||||
local skipped=0
|
||||
local total=$(wc -l < "${test_dir}/classes.list")
|
||||
|
||||
cat "${test_dir}/classes.list" | while read class flags; do
|
||||
|
||||
if [[ $flags =~ "xfail" ]]; then
|
||||
skipped=$(($skipped+1))
|
||||
continue
|
||||
fi
|
||||
|
||||
r=$(test_class_single "${class}" "${flags}")
|
||||
|
||||
if [[ $r == 0 ]]; then
|
||||
passes=$(($passes+1))
|
||||
else
|
||||
fails=$(($fails+1))
|
||||
fi
|
||||
|
||||
echo -en "\r"
|
||||
echo -en "$(($passes + $fails + $skipped))/${total} "
|
||||
echo -en "${GREEN}P:${passes}${NC} "
|
||||
echo -en "${RED}F:${fails}${NC} "
|
||||
echo -en "S:${skipped}${NC} "
|
||||
echo -en " Tested class ${class}"
|
||||
|
||||
# Delete remnant of previous class name
|
||||
# and move cursor back.
|
||||
echo -en " "
|
||||
echo -en "\033[22D"
|
||||
done
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
|
||||
function test_class() {
|
||||
class="$1"
|
||||
flags="$2"
|
||||
|
||||
exists=false;
|
||||
exists=$(
|
||||
cat "${test_dir}/classes.list" | while read tclass flags; do
|
||||
if [[ "${class}" == "${tclass}" ]]; then
|
||||
echo "${class}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
)
|
||||
|
||||
if [[ -z $exists ]]; then
|
||||
echo "No such class "${class}""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "Testing class "${class}"..."
|
||||
r=$(test_class_single "${class}" "${flags}")
|
||||
|
||||
if [[ $r == 0 ]]; then
|
||||
echo -e " ${GREEN}Pass${NC}"
|
||||
else
|
||||
echo -e " ${RED}Fail${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "${2}" in
|
||||
|
||||
"all")
|
||||
test_files
|
||||
test_classes
|
||||
;;
|
||||
|
||||
"files")
|
||||
test_files
|
||||
;;
|
||||
|
||||
"classes")
|
||||
test_classes
|
||||
;;
|
||||
|
||||
"class")
|
||||
test_class "${3}" "${4}"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown test suite `${1}`"
|
||||
echo "See README.md"
|
||||
;;
|
||||
esac
|
Loading…
Reference in New Issue