|
| 1 | +# Render a document |
| 2 | + |
| 3 | +To create a PDF document from an input `.tex` file, send a HTTP POST to the `/render` endpoint. |
| 4 | +You may encode the payload as `multipart/form-data` or `application/x-www-form-encoded`, however |
| 5 | +the latter is not recommended. |
| 6 | + |
| 7 | +Assuming, you have a `input.tex` in the current directory, you can issue the following command |
| 8 | +to send that file to your texd instance, and save the result in a file named `output.pdf`: |
| 9 | + |
| 10 | +```console |
| 11 | +$ curl -X POST \ |
| 12 | + -F "input.tex=<input.tex" \ |
| 13 | + -o "output.pdf" \ |
| 14 | + "http://localhost:2201/render" |
| 15 | +``` |
| 16 | + |
| 17 | +You can send multiple files (even in sub directories) as well: |
| 18 | + |
| 19 | +```console |
| 20 | +$ curl -X POST \ |
| 21 | + -F "cv.tex=<cv.tex" \ |
| 22 | + -F "chapters/introduction.tex=<chapters/introduction.tex" \ |
| 23 | + -F "logo.pdf=<logo.pdf" \ |
| 24 | + -o "vita.pdf" \ |
| 25 | + "http://localhost:2201/render?input=cv.tex" |
| 26 | +``` |
| 27 | + |
| 28 | +When sending multiple files, you should specify which one is the main input file (usually the one |
| 29 | +containing `\documentclass`), using the `input=` query parameter. If you omit this parameter, texd |
| 30 | +will try to guess the input file. |
| 31 | + |
| 32 | +Please note that file names will be normalized, and files pointing outside the root directory |
| 33 | +will be discarded entirely (i.e. `../input.tex` is NOT a valid file name). You can't do this: |
| 34 | + |
| 35 | +```console |
| 36 | +$ curl -X POST \ |
| 37 | + -F "../input.tex=<input.tex" \ |
| 38 | + -o "output.pdf" \ |
| 39 | + "http://localhost:2201/render" |
| 40 | +``` |
| 41 | + |
| 42 | +However, this is perfectly fine: |
| 43 | + |
| 44 | +```console |
| 45 | +$ curl -X POST \ |
| 46 | + -F "input.tex=<../input.tex" \ |
| 47 | + -o "output.pdf" \ |
| 48 | + "http://localhost:2201/render" |
| 49 | +``` |
| 50 | + |
| 51 | +<details><summary>Guessing the input file (click to show details)</summary> |
| 52 | + |
| 53 | +- only filenames starting with alphanumeric character and ending in `.tex` are considered |
| 54 | + (`foo.tex`, `00-intro.tex` will be considered, but not `_appendix.tex`, `figure.png`) |
| 55 | +- files in sub directories are ignored (e.g. `chapters/a.tex`) |
| 56 | +- if only one file in the root directory remains, it is taken as main input |
| 57 | + - otherwise search for a file containing a line starting with: |
| 58 | + - either `%!texd` at the beginning of the file |
| 59 | + - or `\documentclass` somewhere in the first KiB |
| 60 | + - if no match, consider (in order): |
| 61 | + - `input.tex` |
| 62 | + - `main.tex` |
| 63 | + - `document.tex` |
| 64 | + |
| 65 | +</details> |
| 66 | + |
| 67 | +If no main input file can be determined, texd will abort with an error. |
| 68 | + |
| 69 | +## URL Parameters |
| 70 | + |
| 71 | +- `input=<filename>` - instructs texd to skip guessing main input file and use the specified one. |
| 72 | + The filename must be present in the body. |
| 73 | + |
| 74 | +- `engine=<value>` - specifies which TeX engine to run. Supported engines are: |
| 75 | + |
| 76 | + - `xelatex` (default) |
| 77 | + - `lualatex` |
| 78 | + - `pdflatex` |
| 79 | + |
| 80 | + Note that the default can be changed with a CLI option (e.g. `--tex-engine=lualatex`). |
| 81 | + |
| 82 | +- `image=<imagename>` - selects Docker image for document processing. |
| 83 | + |
| 84 | + This is only available in *ephemeral container* mode. The image name must match the ones listed |
| 85 | + in the texd command invocation, i.e. you can't select arbitrary images. |
| 86 | + |
| 87 | + If you provide an unknown image name, you will receive a 404 Not Found response. In *local* and |
| 88 | + *CI service* mode, this parameter only logged, but will otherwise be ignored. |
| 89 | + |
| 90 | +- `errors=<detail level>` - tries to retrieve the compilation log, in case of compilation errors. |
| 91 | + Acceptable detail levels are: |
| 92 | + |
| 93 | + - *empty* (or `errors` completely absent), to return a JSON description (default) |
| 94 | + - `condensed`, to return only the TeX error message from the log file |
| 95 | + - `full`, to return the full log file as `text/plain` response |
| 96 | + |
| 97 | + The "condensed" form extracts only the lines from the error log which start with a `!`. Due to |
| 98 | + the way TeX works, these lines may not paint the full picture, as TeX's log lines generally don't |
| 99 | + exceed a certain line length, and wrapped lines won't get another `!` prefix. |
| 100 | + |
| 101 | + Note that this parameter changes the response content to a plain text file if you select `full` |
| 102 | + or `condensed`, and not a JSON response as in all other cases. |
| 103 | + |
| 104 | +## Successful response |
| 105 | + |
| 106 | +If compilation succeeds, you'll receive a status 200 OK, with content type `application/pdf`, and |
| 107 | +the PDF file as response body. |
| 108 | + |
| 109 | +```http |
| 110 | +HTTP/1.1 200 OK |
| 111 | +Content-Type: application/pdf |
| 112 | +Content-Length: 1234 |
| 113 | +
|
| 114 | +%PDF/1.5... |
| 115 | +``` |
| 116 | + |
| 117 | +## Failure responses |
| 118 | + |
| 119 | +If the request was accepted, but could not complete due to errors, you will by default receive a 422 |
| 120 | +Unprocessable Entity response with content type `application/json`, and an error description in |
| 121 | +JSON format: |
| 122 | + |
| 123 | +```http |
| 124 | +HTTP/1.1 422 Unprocessable Entity |
| 125 | +Content-Type: application/json |
| 126 | +Content-Length: 154 |
| 127 | +
|
| 128 | +{ |
| 129 | + "error": "latexmk call failed with status 1", |
| 130 | + "category": "compilation", |
| 131 | + "output": "[truncated output log]" |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +The fields `error` and `category` represent a short error description and an error category, |
| 136 | +respectively. |
| 137 | + |
| 138 | +Possible, known error categories are currently: |
| 139 | + |
| 140 | +- *input* - one or more files are invalid (e.g. file was discarded after path normalization), |
| 141 | + or the main input file could not be determined. |
| 142 | + |
| 143 | +- *compilation* - `latexmk` exited with an error (likely due to invalid or missing input files). |
| 144 | + |
| 145 | +- *queue* - texd won't accept new render jobs, if its internal queue is at capacity. In this case |
| 146 | + wait for a few moments to give texd a chance to catch up and then try again. |
| 147 | + |
| 148 | +- *reference* - texd could not find the provided reference store entries. The missing references |
| 149 | + are listed in the response; you need to repeat the request with those files included. |
| 150 | + |
| 151 | +Additional fields, like `log` for compilation failures, might be present. |
| 152 | + |
| 153 | +> Note: The JSON response is pretty-printed only for this README. Expect the actual response to |
| 154 | +> be minified. |
| 155 | +
|
| 156 | +If you set `errors=full`, you may receive a plain text file with the compilation log: |
| 157 | + |
| 158 | +<details><summary>Show response (click to open)</summary> |
| 159 | + |
| 160 | +```http |
| 161 | +HTTP/1.1 422 Unprocessable Entity |
| 162 | +Content-Type: text/plain |
| 163 | +Content-Length: 3156 |
| 164 | +
|
| 165 | +This is XeTeX, Version 3.141592653-2.6-0.999993 (TeX Live 2021) (preloaded format=xelatex 2022.3.6) 12 MAR 2022 13:57 |
| 166 | +entering extended mode |
| 167 | + restricted \write18 enabled. |
| 168 | + %&-line parsing enabled. |
| 169 | +... ommitting some lines ... |
| 170 | +! LaTeX Error: File `missing.tex' not found. |
| 171 | +
|
| 172 | +Type X to quit or <RETURN> to proceed, |
| 173 | +or enter new name. (Default extension: tex) |
| 174 | +
|
| 175 | +Enter file name: |
| 176 | +! Emergency stop. |
| 177 | +<read *> |
| 178 | +
|
| 179 | +l.3 \input{missing.tex} |
| 180 | + ^^M |
| 181 | +*** (cannot \read from terminal in nonstop modes) |
| 182 | +``` |
| 183 | + |
| 184 | +</details> |
| 185 | + |
| 186 | +For `errors=condensed`, you'll only receive the lines starting with `!` (with this prefix removed): |
| 187 | + |
| 188 | +<details><summary>Show response (click to open)</summary> |
| 189 | + |
| 190 | +```http |
| 191 | +HTTP/1.1 422 Unprocessable Entity |
| 192 | +Content-Type: text/plain |
| 193 | +Content-Length: 59 |
| 194 | +
|
| 195 | +LaTeX Error: File `missing.tex' not found. |
| 196 | +Emergency stop. |
| 197 | +``` |
| 198 | + |
| 199 | +</details> |
0 commit comments