|
| 1 | +--- |
| 2 | +title: "Engine Extensions" |
| 3 | +--- |
| 4 | + |
| 5 | +Engine extensions are Quarto extensions that provide an execution engine for running code blocks and capturing their output in Quarto documents. |
| 6 | + |
| 7 | +::: callout-important |
| 8 | + |
| 9 | +Currently there is one execution engine per Quarto document, so you can't have some code blocks executed by an engine extension and other code blocks executed by e.g. `jupyter` or `knitr`. |
| 10 | + |
| 11 | +Engine extensions do not allow control over the cell language handlers for [diagrams](/docs/authoring/diagrams.qmd) like `mermaid` and `dot`. |
| 12 | + |
| 13 | +This is likely to improve in the future. |
| 14 | +::: |
| 15 | + |
| 16 | +### Quick Start |
| 17 | + |
| 18 | +Here we'll describe how to create a basic engine extension. We'll use the `quarto create` command to do this. If you are using VS Code, Positron, or RStudio you should execute `quarto create` within their respective integrated Terminal panes. |
| 19 | + |
| 20 | +To get started, execute `quarto create extension engine` within the parent directory where you'd like the engine extension to be created: |
| 21 | + |
| 22 | +```{.bash filename="Terminal"} |
| 23 | +$ quarto create extension engine |
| 24 | +? Extension Name › my-language-engine |
| 25 | +? Default cell language name (my-language-engine) › my-language |
| 26 | +``` |
| 27 | + |
| 28 | +As shown above, you'll be prompted for an engine name and a cell language name for cells, e.g. |
| 29 | + |
| 30 | +````markdown |
| 31 | +```{my-language} |
| 32 | +x = 42 |
| 33 | +``` |
| 34 | +```` |
| 35 | + |
| 36 | +The language name will default to the engine name. Type each name and press Enter---the engine extension is then created: |
| 37 | + |
| 38 | +```bash |
| 39 | +? Extension Name › my-prerender-scripts |
| 40 | +Creating extension at /Users/gordon/src/my-language-engine: |
| 41 | + - Created example.qmd |
| 42 | + - Created README.md |
| 43 | + - Created _extensions/my-language-engine/_extension.yml |
| 44 | + - Created .gitignore |
| 45 | + - Created src/my-language-engine.ts |
| 46 | +? Open With |
| 47 | +❯ positron |
| 48 | + vscode |
| 49 | + rstudio |
| 50 | + (don't open) |
| 51 | +``` |
| 52 | +
|
| 53 | +If you are running within VS Code, Positron, or RStudio a new window will open with the extension project. |
| 54 | +
|
| 55 | +## Contents of Engine Extensions |
| 56 | +
|
| 57 | +The `quarto create extension engine` command has created an `_extensions` directory, which is what gets installed for users of your extension, and a `src` directory containing the TypeScript source. |
| 58 | +
|
| 59 | +The `_extensions/my-language-engine/` directory will contain a Quarto extension configuration like this: |
| 60 | +
|
| 61 | +``` {.yaml filename="_extensions/my-language-engine/_extension.yml"} |
| 62 | +title: My-language-engine |
| 63 | +author: Gordon Woodhull |
| 64 | +version: 1.0.0 |
| 65 | +quarto-required: ">=1.9.0" |
| 66 | +contributes: |
| 67 | + engines: |
| 68 | + - path: my-language-engine.js |
| 69 | +``` |
| 70 | +
|
| 71 | +To generate the JavaScript bundle this points to, run |
| 72 | +
|
| 73 | +```bash |
| 74 | +quarto call build-ts-extension |
| 75 | +``` |
| 76 | +
|
| 77 | +This builds the TypeScript source `src/my-language-engine.ts` against the types and import map distributed with Quarto, and outputs `_extensions/my-language-engine/my-language-engine.js`. |
| 78 | +
|
| 79 | +## How Engine Extensions Work |
| 80 | +
|
| 81 | +The `ExecutionEngineDiscovery` interface specifies |
| 82 | +
|
| 83 | +* an `init` method providing the **Quarto API**[The **Quarto API** is not documented yet. See the Typescript types in [quarto-types](https://github.com/quarto-dev/quarto-cli/tree/main/packages/quarto-types)]{.aside} to the engine |
| 84 | +* methods used in determining which engine to use |
| 85 | +* a `launch` method which takes the `EngineProjectContext` and provides methods for executing cells and capturing output, and returns an `ExecutionEngineInstance`. |
| 86 | +
|
| 87 | +The `ExecutionEngineInstance.execute` method processes the entire markdown of the document after includes and embeds, and before cell language handlers and Pandoc. |
| 88 | +
|
| 89 | +For the languages that it claims, it should replace each code block with: |
| 90 | +
|
| 91 | +1. If `options.format.execute.echo` is true, the same code block in non-executable syntax. |
| 92 | +
|
| 93 | + E.g. if the input is |
| 94 | +
|
| 95 | + ````markdown |
| 96 | + ```{{python}} |
| 97 | + ``` |
| 98 | + ```` |
| 99 | +
|
| 100 | + Then the output should be |
| 101 | +
|
| 102 | + ````markdown |
| 103 | + ``` {.python} |
| 104 | + ``` |
| 105 | + ```` |
| 106 | +
|
| 107 | + adding other classes and attributes as appropriate. |
| 108 | +
|
| 109 | + If `echo` is false, the code should not be output. |
| 110 | +2. Any outputs from executing the code block, depending on `options.format.execute.output` |
| 111 | +
|
| 112 | +See [Execution Options](/docs/computations/execution-options.qmd) for more information on execution options. |
0 commit comments