Writing in Weibian [0008]
Writing in Weibian [0008]
Weibian works by compiling a Typst bundle. The process is intentionally thin: it discovers Typst files and public assets, generates a small entrypoint in memory, and pipes that entrypoint to the Typst compiler which compiles to the bundle target. Rendering behavior lives in Typst templates.
Rendering Process [rendering-process]
Rendering Process [rendering-process]
To quickly get started, use the default templates in the typ directory in the repository of Weibian. Those templates define note pages, transclusions, links, citations, backmatter, and table of contents using Typst’s bundle export and introspection features.
At compile time, Weibian scans input_dir recursively and collects .typ files whose paths match the configured include/exclude globs. These globs are matched relative to input_dir, and exclude rules have priority. Weibian then generates an entrypoint containing one root-relative include per discovered source:
#include "/@@0008--writing-in-weibian.typ"
#include "/blog/@@0001--typst-finds-a-sweet-spot-for-taking-scientific-notes.typ"Weibian also scans public_dir for regular files and emits bundle assets. public_dir must be inside input_dir; when it is relative, it is resolved under input_dir, so public_dir = "public" means typ/public for the default project layout.
#asset("css/weibian.css", read("/public/css/weibian.css", encoding: none))The generated entrypoint is not written to disk. Conceptually, Weibian runs:
typst compile --features=bundle,html --format=bundle --root=typ - distThe templates loaded by the included files are responsible for constructing document(...) values for HTML pages and PDFs. In the default templates, each note calls #show: template(...); the template wraps the note body in a bundle document, records note metadata through Typst labels/metadata, and uses Typst context and introspection to render transclusions, backlinks, contexts, references, related links, and the table of contents.
The linking helpers such as ln, ct, and tr are ordinary Typst functions supplied by the template. This means Weibian no longer emits or consumes custom HTML elements, no longer parses intermediate HTML, and no longer renders Tera templates.
Using Configuration File [using-configuration-file]
Using Configuration File [using-configuration-file]
Weibian supports a weibian.toml configuration file in the current directory to set project options such as input/output directories, the public assets directory, include/exclude globs, and site options. CLI flags override config values.
The following is an example configuration file:
[files]
input_dir = "typ"
output_dir = "dist"
public_dir = "public"
include = ["**/*.typ"]
exclude = ["index.typ", "_template/*.typ"]
[site]
domain = "example.com"
root_dir = "/"
trailing_slash = trueIf you keep a handwritten bundle entrypoint such as typ/index.typ, exclude it explicitly. Weibian respects filters exactly and will include index.typ if the filters allow it.
The [site] settings are passed to the Typst compiler as --input values:
wb-domainwb-root-dirwb-trailing-slash
The default templates use these inputs for link generation. The root_dir and trailing_slash values do not directly determine where Rust writes files; bundle output paths are chosen by the Typst document(...) elements created by the templates.
wb compile also mirrors most Typst compile options, including --input, font and package paths, --creation-timestamp, --pretty, --pages, --pdf-standard, --no-pdf-tags, --ppi, --deps, --deps-format, --jobs, --diagnostic-format, --open, and --timings. Weibian owns the input path, output path, Typst root, output format, and required experimental features.
Use Emacs denote package to write in Weibian [0009]
Use Emacs denote package to write in Weibian [0009]
If you use Emacs, Weibian is accompanied by an Emacs Lisp package providing the integration of Weibian and the Denote package. The following is an example of configuration. However, since everyone has different templates, there’s a lot of variables to tweak, and you need to read the source code of the package (it’s not very big though) to understand how to customize it. A rewrite of the package to make it more idiomatic is planned.
(use-package denote
:bind (("C-c n n" . denote)) ;; add your keybindings
:config
(setq denote-directory (expand-file-name "~/Documents/notes/typ/"))
(setq denote-prompts '(signature title))
(setq denote-excluded-directories-regexp "_template")
;;; Use incrementing base-36 numbers as id
;;; This function assumes that IDENTIFIERS is a list of base-36 strings
;;; i.e. 4-character strings consisting of numbers and uppercase letters
(defun my/denote-get-next-base36 (identifiers)
(let ((maxs nil))
(dolist (s identifiers)
(let ((u (upcase s)))
(when (or (null maxs) (string> u maxs))
(setq maxs u))))
;; increment maxs
(let ((buf (copy-sequence maxs))
(i 3)
(carry 1))
(while (and (>= i 0) (= carry 1))
(let* ((d (aref buf i)))
(if (= d ?Z)
(progn
(aset buf i ?0)
(setq carry 1))
(if (= d ?9)
(aset buf i ?A)
(aset buf i (+ d 1)))
(setq carry 0)))
(setq i (1- i)))
buf)))
(defun my/denote-generate-base36-identifier (initial-identifier _date)
(let ((denote-used-identifiers (or denote-used-identifiers (denote--get-all-used-ids))))
(cond (;; Always use the supplied initial-identifier if possible,
;; regardless of format.
(and initial-identifier
(not (gethash initial-identifier denote-used-identifiers)))
initial-identifier)
(;; Else, the supplied initial-identifier is nil or it is already
;; used. Ignore it and generate a valid identifier with the right
;; format.
t
(let* ((identifiers (hash-table-keys denote-used-identifiers))
(case-fold-search nil)
(base36-identifiers (seq-filter (lambda (id) (string-match-p "[0-9A-Z]\\{4\\}" id)) identifiers)))
(if base36-identifiers
(my/denote-get-next-base36 base36-identifiers)
"0000"))))))
(setq denote-get-identifier-function #'my/denote-generate-base36-identifier))
(use-package typst-ts-mode)
(use-package denote-weibian
:load-path "/path/to/weibian/directory/"
:after (denote)
:demand t
:bind (("C-c n b" . denote-backlinks)
("C-c n c" . denote-weibian-contexts)
("C-c n t" . denote-weibian-transclude))
:config
(push denote-weibian-file-type denote-file-types)
;; Optional: prompt for selected #tr keyword arguments.
(setq denote-weibian-transclusion-prompts
'(show-metadata expanded))
(setq denote-file-name-slug-functions
'((title . denote-sluggify-title)
(signature . identity)
(keyword . denote-sluggify-keyword))))By default, denote-weibian-transclude inserts a bare #tr("wb:ID"), which leaves all optional arguments to the default values defined by your Typst template. Set denote-weibian-transclusion-prompts if you want to be asked for selected #tr options every time. For a one-off insertion that prompts for all transclusion options, call denote-weibian-transclude with C-u.