mc-zen / tidy Goto Github PK
View Code? Open in Web Editor NEWA documentation generator for Typst in Typst.
Home Page: https://typst.app/universe/package/tidy
License: MIT License
A documentation generator for Typst in Typst.
Home Page: https://typst.app/universe/package/tidy
License: MIT License
It would be nice if the fact that the default styles require Cascadia Mono is documented somewhere. Although this font is available in the webapp, it's probably not installed by default on non Microsoft systems.
Dear developer,
I just tied to use tidy with typst 0.11.0.
I copied /SRC to examples and then run
typst c wiggly-doc.typ
instead of building the help, I got several errors.
~/tools/ty/tidy/examples on main !1 ?1 > typst c wiggly-doc.typ
error: unknown variable: draw-sine
┌─ src/show-example.typ:48:23
│
48 │ let preview = [#eval(preamble + code.text, mode: mode, scope: scope + inherited-scope)]
│ ^^^^^^^^^^^^^^^^^^^^
│
= hint: if you meant to use subtraction, try adding spaces around the minus sign
help: error occurred in this call of function show-example
┌─ src/styles/minimal.typ:165:2
│
165 │ ╭ show-ex(
166 │ │ ..args,
167 │ │ code-block: block.with(stroke: .5pt + fn-color),
168 │ │ preview-block: block.with(stroke: .5pt + fn-color),
169 │ │ col-spacing: 0pt
170 │ │ )
│ ╰───^
help: error occurred in this call of function show-example
┌─ src/utilities.typ:35:7
│
35 │ eval(content, mode: "markup", scope: scope)
│ ^^^^^^^
help: error occurred in this call of function eval
┌─ src/utilities.typ:35:2
│
35 │ eval(content, mode: "markup", scope: scope)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: error occurred in this call of function eval-docstring
┌─ src/styles/minimal.typ:102:14
│
102 │ pad(x: 0em, eval-docstring(fn.description, style-args))
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: error occurred in this call of function show-function
┌─ src/show-module.typ:120:4
│
120 │ (style-functions.show-function)(fn, style-args)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: error occurred in this call of function show-module
┌─ wiggly-doc.typ:9:1
│
9 │ #show-module(docs, style: styles.minimal) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
what am doing wrong?
Thank you so much for your help.
As per title, functions defined by currying are treated as variables rather than functions. Perhaps, could Tidy check if a variable is set using .with()
, and import the documentation (if any) for that function? (recursively)
The @@ommand()
syntax is a nice addition. Maybe the final display of the reference could be passed to the style, to allow customization of the final reference?
For example, I integrated tidy
with my template for package manuals Mantys and would like to format all commands in the manual with the same #cmd()
function.
It could be done with a new function in the style called show-function-reference( location, fn )
or similar.
It would be nice to be able to structure the documentation by allowing additional markup in a module file, that is not attached to a function. For example:
/// == Utility functions
/// The following functions are utilities.
/// A foo function.
#let foo(a, b) = [#a-#b]
/// == Math functions
/// Some math markup
#let inv(x) = $1/x$
After rendering and parsing, the headings and descriptive text would render between function documentation.
Open question:
sort-function
?It seems that the labels of str
and int
type is different between tidy
and Typst's official documentation, where
the string
type is str
https://typst.app/docs/reference/foundations/str/
the integer
type is int
https://typst.app/docs/reference/foundations/int/
It seems that in old version of Typst, type(1)
yields "integer"
, so is this a legacy or is it intended?
#import "@preview/tidy:0.2.0": show-example
#show raw: show-example.show-example
```typ
Hello world
```
Produces the error
error: variables from outside the function are read-only and cannot be modified
┌─ @preview/tidy:0.2.0\src\show-example.typ:32:4
│
32 │ mode = "markup"
│ ^^^^
Here's a minimal example with three modules given as inline code:
#import "@preview/tidy:0.2.0"
#tidy.show-module(
tidy.parse-module(````
/// A function
///
/// #example(mode: "markup", ```
/// #rect(width: 2em)
/// ```)
#let func-a() = {}
````.text),
style: tidy.styles.minimal
)
// #tidy.show-module(
// tidy.parse-module(````
// /// A function
// ///
// /// #example(mode: "markup", ```
// /// #rect(width: 100%)
// /// ```)
// #let func-b() = {}
// ````.text),
// style: tidy.styles.minimal
// )
#tidy.show-module(
tidy.parse-module(````
/// A function
///
/// #example(mode: "markup", scale-preview: 100%, ```
/// #rect(width: 100%)
/// ```)
#let func-c() = {}
````.text),
style: tidy.styles.minimal
)
The first module contains a func-a
, and its documentation has an example. The width is 2em
(plus some border) - no problem.
However, the second module (commented out) has a rectangle with width: 100%
. This leads to a division by zero, it seems:
error: cannot divide by zero
┌─ @preview/tidy:0.2.0/src/show-example.typ:59:16
│
59 │ calc.min(1, available-preview-width / preview-size.width) * 100%
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The third module circumvents this: the division only happens if scale-preview == auto
, so I set scale-preview: 100%
. However, this seems to give the example content a "viewport" width of zero: width: preview-size.width * (scale-preview / 100%)
.
So in total: examples can't have a width that is a ratio, as measuring that leads to either dividing by or multiplying with zero.
For packages, especially templates, if one is only useful in a specific language that is not English, such as University thesis in monolingual countries (in Chinese or Japanese, etc.), or if a pacakge want to provided multi-lingual documentation, localization will become a requirement.
There are some baked-in strings such as Parameters
and Defaults:
that are currently customizable through custom styles. However, If one only wants to change the locale but keep the styles the same, it would be very much cost to do that. Instead, it would be helpful to allow localization through style-args
.
When requesting the description of a sink parameter, e.g.,
#my-module.help("func(children)")
the corresponding parameter is not found and #my-module.help("func(..children)")
does not work either.
Line 122 adds a vertical space of 3em
after each function. Maybe this could be moved to the style, to allow custom spacing for different templates.
When the default tidy style is applied to a page with a black background & white text, the styling prevents visibility:
However, if you added transparency to every color in the style list, the light mode is unaffected and the dark mode looks fine:
Relevant changes:
#import "@preview/tidy:0.1.0"
#import tidy.styles.default: *
#let show-parameter-block(
name, types, content, style-args,
show-default: false,
default: none,
) = block(
inset: 10pt, fill: rgb("ddd3"), width: 100%,
breakable: style-args.break-param-descriptions,
[
#text(weight: "bold", size: 1.1em, name)
#h(.5cm)
#types.map(x => (style-args.style.show-type)(x)).join([ #text("or",size:.6em) ])
#content
#if show-default [ #parbreak() Default: #raw(lang: "typc", default) ]
]
)
#let type-colors = (
"content": rgb("#a6ebe699"),
"color": rgb("#a6ebe699"),
"string": rgb("#d1ffe299"),
"none": rgb("#ffcbc499"),
"auto": rgb("#ffcbc499"),
"boolean": rgb("#ffedc199"),
"integer": rgb("#e7d9ff99"),
"float": rgb("#e7d9ff99"),
"ratio": rgb("#e7d9ff99"),
"length": rgb("#e7d9ff99"),
"angle": rgb("#e7d9ff99"),
"relative-length": rgb("#e7d9ff99"),
"fraction": rgb("#e7d9ff99"),
"symbol": rgb("#eff0f399"),
"array": rgb("#eff0f399"),
"dictionary": rgb("#eff0f399"),
"arguments": rgb("#eff0f399"),
"selector": rgb("#eff0f399"),
"module": rgb("#eff0f399"),
"stroke": rgb("#eff0f399"),
"function": rgb("#f9dfff99"),
)
#let get-type-color(type) = type-colors.at(type, default: rgb("#eff0f333"))
// Create beautiful, colored type box
#let show-type(type) = {
h(2pt)
box(outset: 2pt, fill: get-type-color(type), radius: 2pt, raw(type))
h(2pt)
}
I encountered an issue where tidy fails with an error in a specific document case.
The module is called qrutil.typ
and looks like this:
// aliases
#let mod = calc.rem
#let mod2(x) = calc.rem(x, 2)
#let mod3(x) = calc.rem(x, 3)
#let mod255(x) = calc.rem(x, 255)
#let mod256(x) = calc.rem(x, 256)
#let mod285(x) = calc.rem(x, 285)
/// >>> qrutil.check-version(1)
/// >>> qrutil.check-version(30)
/// >>> qrutil.check-version(40)
/// >>> not qrutil.check-version(0)
/// >>> not qrutil.check-version(41)
#let check-version(version) = version >= 1 and version <= 40
/// >>> qrutil.check-ecl("l")
/// >>> qrutil.check-ecl("h")
/// >>> qrutil.check-ecl("m")
/// >>> qrutil.check-ecl("q")
/// >>> not qrutil.check-ecl("a")
/// >>> not qrutil.check-ecl("Q")
#let check-ecl(ecl) = ecl in ("l", "m", "q", "h")
/// >>> qrutil.size(1) == 21
/// >>> qrutil.size(2) == 25
/// >>> qrutil.size(33) == 149
/// >>> qrutil.size(40) == 177
#let size(version) = { return 21 + (version - 1)*4 }
// =================================
// Encoding
// =================================
/// >>> qrutil.best-mode("0123") == 0
/// >>> qrutil.best-mode("0000") == 0
/// >>> qrutil.best-mode("1") == 0
/// >>> qrutil.best-mode("A") == 1
/// >>> qrutil.best-mode("ABCD") == 1
/// >>> qrutil.best-mode("ABCD:XYZ$") == 1
/// >>> qrutil.best-mode("a") == 2
/// >>> qrutil.best-mode("abcxyz") == 2
/// >>> qrutil.best-mode("ABCD:XYZ!") == 2
/// >>> qrutil.best-mode("@€") == none
#let best-mode(data) = {
let nums = regex(`^\d*$`.text)
let alphnum = regex(`^[\dA-Z $%*+\-./:]*$`.text)
let byte = regex(`^[\x00-\xff]*$`.text)
if data.match(nums) != none {
return 0
}
if data.match(alphnum) != none {
return 1
}
if data.match(byte) != none {
return 2
}
return none
}
/// foo
#let mode-bits(mode) = {
return (
(false, false, false, true),
(false, false, true, false),
(false, true, false, false),
(true, false, false, false)
).at(mode)
}
The minimal manual code:
#import "@local/tidy:0.1.0"
#import "qrutil.typ"
#let doc = tidy.parse-module(
read("qrutil.typ"),
name: "qrutil",
scope: (
qrutil: qrutil
)
)
#tidy.show-module(doc)
The error I get:
error: string index 1303 is not a character boundary
┌─ @local/tidy:0.1.0/src/tidy-parse.typ:219:7
│
219 │ if string.at(i) == char { count += 1}
│ ^^^^^^^^^^^^
help: error occurred in this call of function `count-occurences`
┌─ @local/tidy:0.1.0/src/tidy-parse.typ:254:26
│
254 │ let first-line-number = count-occurences(source-code, "\n", end: match.start) + 1
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: error occurred in this call of function `parse-function-docstring`
┌─ @local/tidy:0.1.0/src/tidy.typ:57:23
│
57 │ function-docs.push(tidy-parse.parse-function-docstring(content, match, parse-info))
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: error occurred in this call of function `parse-module`
┌─ /manual.typ:5:11
│
5 │ #let doc = tidy.parse-module(
│ ╭────────────^
6 │ │ read("qrutil.typ"),
7 │ │ name: "qrutil",
8 │ │ scope: (
9 │ │ qrutil: qrutil
10 │ │ )
11 │ │ )
│ ╰─^
I wanted to add an image to the documentation, but got the error cannot access file system from here
. I'm sorry if I overlooked a possibility to already do that, but if not, I think adding it would be awesome.
It would be nice to allow arbitrary options to be passed to #show-module
that are available to themes in #style-args.options
. This would allow themes to define custom options beyond the ones Tidy offers for further customization of the output. For example, a theme could allow users to pass in a primary
color, that changes the style of the output.
I see two possible implementations:
#show-module
collects any unknown named arguments into #style-args.options
.#show-module
accepts a new parameter theme-options
.Reproducing example:
#import "@preview/tidy:0.3.0"
#let module = ````
/// #example(```
/// [a #raw("foo") b]
/// ```)
let x = none
````.text
#let module = tidy.parse-module(
module,
)
#tidy.show-module(
module,
sort-functions: none,
style: tidy.styles.minimal,
)
This uses #raw("foo")
in an example. By default, this would not result in inline raw content, but due to this line it becomes a block. If I understand the intent behind it correctly, I think this could go here instead.
Thank you for this project!
In CeTZ we use a lot of var-args my-fun(..options)
, but I could find no way to
get typst-doc to match the argument to my docstring line:
//// my-fun
/// - ..options (any): Text
does not work. Is this currently possible?
The setting seems to be ignored, because the description is compared to []
(empty content), but the default is ""
(empty string). See styles/default.typ:114 for example.
I think something like if description in ("", []) ...
would work better.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.