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

feat(pkg::core): add snippet (all-in-one) library #381

Merged
merged 4 commits into from
Oct 29, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/gh_pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | bash
- name: Download & install typst-book
run: |
curl -L https://github.com/Myriad-Dreamin/typst-book/releases/download/v0.1.2-nightly1/typst-book-x86_64-unknown-linux-gnu.tar.gz | tar -xvz
curl -L https://github.com/Myriad-Dreamin/typst-book/releases/download/v0.1.2-nightly2/typst-book-x86_64-unknown-linux-gnu.tar.gz | tar -xvz
chmod +x typst-book-x86_64-unknown-linux-gnu/bin/typst-book
sudo cp typst-book-x86_64-unknown-linux-gnu/bin/typst-book /usr/bin/typst-book
- name: Run sccache-cache
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ cargo install --locked --git https://github.com/Myriad-Dreamin/typst.ts typst-ts

Or Download the latest release from [GitHub Releases](https://github.com/Myriad-Dreamin/typst.ts/releases).

### Example: Render Typst document in browser (build from source with/without wasm-pack)
### Documentation

See [Documentation](https://myriad-dreamin.github.io/typst.ts/cookery).

### Build from source and check

Note: you could build from source with/without wasm-pack.

Note: see [Troubleshooting WASM Build](docs/troubleshooting-wasm-build.md) for (especially) **Arch Linux** users.

Expand All @@ -103,11 +109,11 @@ And open your browser to `http://localhost:20810/`.
You can also run `yarn run build:core` instead of `npx turbo run build` to build
core library (`@myriaddreamin/typst.ts`) and avoid building the WASM modules from source.

### Example: generate documentation site for packages developers.
<!-- ### Example: generate documentation site for packages developers.

- Link [typst-doc](https://github.com/Mc-Zen/typst-doc) by `typst-ts-cli package link --manifest ./typst.toml`.

- Generate documentation by `typst-ts-cli package doc --manifest ./contrib/templates/typst-ts-templates/typst.toml`.
- Generate documentation by `typst-ts-cli package doc --manifest ./contrib/templates/typst-ts-templates/typst.toml`. -->

### Concept: Precompiler

Expand Down
3 changes: 2 additions & 1 deletion docs/cookery/book.typ
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
#prefix-chapter("introduction.typ")[Introduction]
= Quickstart
- #chapter("get-started.typ", section: "1")[Get started]
- #chapter(none, section: "1.1")[All-in-one JavaScript Library]
- #chapter("guide/all-in-one.typ", section: "1.1")[All-in-one JavaScript Library]
- #chapter("guide/compilers.typ", section: "2")[Compilers]
- #chapter("guide/compiler/ts-cli.typ", section: "2.1")[Command Line Interface]
- #chapter("guide/compiler/service.typ", section: "2.2")[Compiler Service Library]
- #chapter("guide/compiler/serverless.typ", section: "2.3")[Serverless (In-browser) Compiler]
- #chapter("guide/compiler/node.typ", section: "2.4")[Compiler for Node.js]
- #chapter("guide/e2e-renderers.typ", section: "3")[End-to-end Renderers]
- #chapter(none, section: "3.1")[React Library]
- #chapter(none, section: "3.2")[Angular Library]
Expand Down
15 changes: 15 additions & 0 deletions docs/cookery/get-started.typ
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ const getModule = () => WebAssembly.instantiate(/* params */);
const getModule = async () => {/* above four ways */};
```

== Run the compiler or renderer with simplified APIs

The most simple examples always work with the all-in-one JavaScript Library:

```ts
import { $typst } from '@myriaddreamin/typst.ts/dist/esm/contrib/snippet.mjs';
console.log((await $typst.svg({
mainContent: 'Hello, typst!' })).length);
// :-> 7317
```

See #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/all-in-one.html")[All-in-one (Simplified) JavaScript Library] for more example usage.

Once you feel more conformtable, please continue reading following sections.

== Configure and run compiler <run-compiler>

- Configure font resources
Expand Down
149 changes: 149 additions & 0 deletions docs/cookery/guide/all-in-one.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#import "/docs/cookery/book.typ": book-page

#show: book-page.with(title: "All-in-one (Simplified) JavaScript Library")

= All-in-one (Simplified) JavaScript Library

#let snippet-source = "https://github.com/Myriad-Dreamin/typst.ts/blob/main/packages/typst.ts/src/contrib/snippet.mts"
#let snippet-lib = link(snippet-source)[`snippet`]

The most simple examples always work with #snippet-lib utility library, an all-in-one JavaScript Library with simplified API interfaces:

```ts
import { $typst } from '@myriaddreamin/typst.ts/dist/esm/contrib/snippet.mjs';
console.log((await $typst.svg({
mainContent: 'Hello, typst!' })).length);
// :-> 7317
```

However, it is less flexible and stable than the underlying interfaces, the `TypstCompiler` and `TypstRenderer`. If you've become more familar with typst.ts, we recommend you rewrite your library with underlying interfaces according to example usage shown by the #snippet-lib library.

Note: If your script targets to *CommonJS*, you should import it in *CommonJS* path instead of In *ES Module* path:

```ts
const { createTypstCompiler } = require(
'@myriaddreamin/typst.ts/dist/cjs/compiler.cjs');
```

== Examples

Here are some examples for the #snippet-lib utility library.

=== Example: Use the _global shared_ compiler instance:

```typescript
import { $typst } from '@myriaddreamin/typst.ts/dist/esm/contrib/snippet.mjs';
```

Note: if you want to compile multiple documents, you should create a new instance for each compilation work or maintain the shared state on the utility instance `$typst` carefully,
because the compilation process may change the state of that.

=== Example: Create an instance of the utility class:

```typescript
// optional renderer instance
const renderer = enableRendering ?? (() => {
return createGlobalRenderer(createTypstRenderer,
undefined /* pdfJsLib */, initOptions);
});
const $typst = new TypstSnippet(() => {
return createGlobalCompiler(createTypstCompiler,
initOptions);
}, renderer);
```

=== Example: get output from input

get output with *single input file*:

```ts
const mainContent = 'Hello, typst!';
// into vector format
await $typst.vector({ mainContent });
// into svg format
await $typst.svg({ mainContent });
// into pdf format
await $typst.pdf({ mainContent });
// into canvas operations
await $typst.canvas(div, { mainContent });
```

get output with *multiple input files*:

```ts
// the default value of main path is '/main.typ'
await $typst.addSource('/main.typ', mainContent);

// set path to main file
const mainFilePath = '/tasks/1/main.typ';
await $typst.setMainFilePath(mainFilePath)
await $typst.addSource(mainFilePath, mainContent);
```

What is quite important is that, when you are running multiple tasks asynchronously or in parallel, the call pattern `await $typst.xxx({ mainContent });` is unsafe (introduces undefined behavior). Insteadly you should call compilation by specifying path to the main file:

```ts
const mainFilePath = '/tasks/1/main.typ';
await $typst.addSource(mainFilePath, mainContent);

// compile source of path
await $typst.svg({ mainFilePath });
```

get output with *binary input files*:

```ts
const encoder = new TextEncoder();
// add a json file (utf8)
compiler.mapShadow('/assets/data.json', encoder.encode(jsonData));
// remove a json file
compiler.unmapShadow('/assets/data.json');

// add an image file
const pngData = await fetch(...).arrayBuffer();
compiler.mapShadow('/assets/tiger.png', new Uint8Array(pngData));
```

clean up shadow files for underlying access model:

```ts
compiler.resetShadow();
```

Note: this function will also clean all files added by `addSource`.

=== Example: reuse compilation result

The compilation result could be stored in an artifact in #link("https://github.com/Myriad-Dreamin/typst.ts/blob/main/docs/proposals/8-vector-representation-for-rendering.typ")[_Vector Format_], so that you could decouple compilation from rendering or make high-level cache compilation.

```ts
const vectorData = await $typst.vector({ mainContent });
// into svg format
await $typst.svg({ vectorData });
// into canvas operations
await $typst.canvas(div, { vectorData });
```

Note: the compilation is already cached by typst's `comemo` implicitly.

== Specify extra init options

Ideally, you don't have to specify any options. But if necessary, the extra init options must be at the start of the main routine, or accurately before all invocations.

```ts
// Example: cache default fonts to file system
$typst.setCompilerInitOptions(await cachedFontInitOptoins());
// specify init options to renderer
$typst.setRendererInitOptions(rendererInitOptions);
// wire other `pdfJsLib` instance for renderer
$typst.setPdfjsModule(pdfJsLib);

// The compiler instance is initialized in this call.
await $typst.svg({ mainContent });
```

Note: There are more documentation about initialization in the *Import typst.ts to your project* section of #link("https://myriad-dreamin.github.io/typst.ts/cookery/get-started.html")[Get started with Typst.ts].

== Specify extra render options

See #link(snippet-source)[comments on source] for more details.
7 changes: 7 additions & 0 deletions docs/cookery/guide/compiler/node.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#import "/docs/cookery/book.typ": book-page

#show: book-page.with(title: "Compiler for Node.js")

= Compiler for Node.js

We are actively work on documentation, but you could take reference from #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/compiler/serverless.html")[Serverless Compiler].
74 changes: 73 additions & 1 deletion docs/cookery/guide/compiler/serverless.typ
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,76 @@

= Serverless Compiler

Sample page
#let snippet-source = "https://github.com/Myriad-Dreamin/typst.ts/blob/main/packages/typst.ts/src/contrib/snippet.mts"
#let snippet-lib = link(snippet-source)[`snippet`]

The most simple examples always work with #snippet-lib utility library, an all-in-one JavaScript Library with simplified API interfaces:

```ts
import { $typst } from '@myriaddreamin/typst.ts/dist/esm/contrib/snippet.mjs';
console.log((await $typst.svg({
mainContent: 'Hello, typst!' })).length);
// :-> 7317
```

Please check #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/all-in-one.html")[All-in-one (Simplified) JavaScript Library] for more details.

Quick example for the harder way to serverless compiler:

```ts
import { createTypstCompiler } from '@myriaddreamin/typst.ts';

const mainFilePath = '/main.typ';
const cc /* compiler */ = createTypstCompiler();
await cc.init();
cc.addSource(mainFilePath, 'Hello, typst!');
await cc.compile({ mainFilePath });
```

Note: For #link("https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking")[_tree-shaking_], you should import it with longer path:

In *ES Module* path:

```ts
import { createTypstCompiler } from '@myriaddreamin/typst.ts/dist/esm/compiler.mjs';
```

Or in *CommonJS* path:

```ts
const { createTypstCompiler } = require('@myriaddreamin/typst.ts/dist/cjs/compiler.cjs');
```

== Add or remove source/binary files

You can also use the `{map,unmap,reset}Shadow` function to manipulate any text or binary file data for typst compiler. They will shadow the file access from provided access model directly in memory.

The `mapShadow(path: string, content: Uint8Array): void;` resembles `addSource(path: string, source: string): void;`, but retrieves some binary data without guessing the underlying encoding.

Example usage:

```ts
const encoder = new TextEncoder();
// add a json file (utf8)
compiler.mapShadow('/assets/data.json', encoder.encode(jsonData));
// remove a json file
compiler.unmapShadow('/assets/data.json');
// clean up all shadow files (Note: this function will also clean all files added by `addSource`)
compiler.resetShadow();

// add an image file
const pngData = await fetch(...).arrayBuffer();
compiler.mapShadow('/assets/tiger.png', new Uint8Array(pngData));
```

== Specify output format

Export document as #link("https://github.com/Myriad-Dreamin/typst.ts/blob/main/docs/proposals/8-vector-representation-for-rendering.typ")[_Vector Format_] which can then load to the renderer to render the document.

```ts
const artifactData = await compiler.compile({
mainFilePath: '/main.typ',
// the default value of format field:
// format: 'vector',
});
```
7 changes: 6 additions & 1 deletion docs/cookery/guide/compilers.typ
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@

= Compilers

Sample page
See:

+ #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/compiler/ts-cli.html")[Command Line Interface]
+ #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/compiler/service.html")[Compiler Service Library]
+ #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/compiler/serverless.html")[Serverless (In-browser) Compiler]
+ #link("https://myriad-dreamin.github.io/typst.ts/cookery/guide/compiler/node.html")[Compiler for Node.js]
8 changes: 7 additions & 1 deletion docs/cookery/templates/page.typ
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
"Source Han Serif TC",
)

#let main-font-size = if is-web-target {
16pt
} else {
12pt
}

#let code-font = (
"BlexMono Nerd Font Mono",
// typst-book's embedded font
Expand Down Expand Up @@ -98,7 +104,7 @@
) if is-web-target;

// set text style
set text(font: main-font, size: 16pt, fill: main-color, lang: "en")
set text(font: main-font, size: main-font-size, fill: main-color, lang: "en")

set line(stroke: main-color)

Expand Down
5 changes: 4 additions & 1 deletion packages/compiler/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# typst-ts-web-compiler

See [Typst.ts](https://github.com/Myriad-Dreamin/typst.ts)
The compiler can run in both the browser and node.js. See documentation for details:

- [Get Started](https://myriad-dreamin.github.io/typst.ts/cookery/get-started.html)
- [Compiler interfaces](https://myriad-dreamin.github.io/typst.ts/cookery/guide/compilers.html)
4 changes: 3 additions & 1 deletion packages/renderer/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# typst-ts-renderer

See [Typst.ts](https://github.com/Myriad-Dreamin/typst.ts)
See [Typst.ts](https://github.com/Myriad-Dreamin/typst.ts) and documentation:

- [Get Started](https://myriad-dreamin.github.io/typst.ts/cookery/get-started.html)
3 changes: 3 additions & 0 deletions packages/templates/node.js-compiler-next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

```shell
yarn install
# use snippet below to run
npx tsc && node ./dist/esm/main.snippet.js
# full example
npx tsc && node ./dist/esm/main.js
```
Loading
Loading