Compare commits
7 Commits
9f8bf02522
...
v0.1.0
Author | SHA1 | Date | |
---|---|---|---|
6f502f2e18
|
|||
03e9904d43
|
|||
b8a84b1430 | |||
94d4ac8328
|
|||
01fe756862
|
|||
995564382a
|
|||
7c62a16146
|
@ -1,9 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## [v0.0.2] - _WIP_
|
||||
## [v0.1.0] - 2024-10-02
|
||||
- prepared for publication in Typst Universe
|
||||
|
||||
## [v0.0.2] - 2024-06-15
|
||||
### Added
|
||||
- `width` parameter to `schema.render` for easier integration
|
||||
- `all-bit-i` config option
|
||||
- colored ranges
|
||||
- format specification in the manual
|
||||
|
||||
## [v0.0.1] - 2024-05-19
|
||||
- initial version
|
||||
|
11
README.md
11
README.md
@ -31,14 +31,11 @@ It is based on the [homonymous Python script](https://git.kb28.ch/HEL/rivet/)
|
||||
*Click on the example image to jump to the code.*
|
||||
|
||||
## Usage
|
||||
For information, see the [manual](manual.pdf)
|
||||
For more information, see the [manual](manual.pdf)
|
||||
|
||||
To use this package, simply import `schema` [src/lib.typ](src/lib.typ) and call `schema.load` to parse a schema description. Then use `schema.render` to render it, et voilà !
|
||||
To use this package, simply import `schema` from [rivet](https://typst.app/universe/package/rivet) and call `schema.load` to parse a schema description. Then use `schema.render` to render it, et voilà !
|
||||
```typ
|
||||
#import "src/lib.typ": schema
|
||||
#import "@preview/rivet:0.1.0": schema
|
||||
#let doc = schema.load("path/to/schema.yaml")
|
||||
#schema.render(doc)
|
||||
```
|
||||
|
||||
## Installing
|
||||
> TODO
|
||||
```
|
@ -101,5 +101,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"colors": {
|
||||
"main": {
|
||||
"31-28": "#FF0000",
|
||||
"11-4": [34, 176, 43]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
gallery/test.pdf
BIN
gallery/test.pdf
Binary file not shown.
@ -65,4 +65,7 @@
|
||||
<description>offset register</description>
|
||||
</range>
|
||||
</structure>
|
||||
<color structure="main" color="#FF0000" start="28" end="31" />
|
||||
<color structure="main" color="#255961" start="4" end="11" />
|
||||
<color structure="immediateOffset" color="89,97,37" start="4" end="11" />
|
||||
</schema>
|
@ -71,3 +71,11 @@ structures:
|
||||
3-0:
|
||||
name: Rm
|
||||
description: offset register
|
||||
|
||||
colors:
|
||||
main:
|
||||
31-28: "#3EFA6B"
|
||||
25-23:
|
||||
- 100
|
||||
- 150
|
||||
- 200
|
BIN
manual.pdf
BIN
manual.pdf
Binary file not shown.
198
manual.typ
198
manual.typ
@ -1,4 +1,6 @@
|
||||
#import "@preview/tidy:0.3.0"
|
||||
#import "@preview/codelst:2.0.1": sourcecode
|
||||
#import "@preview/showybox:2.0.1": showybox
|
||||
#import "src/lib.typ"
|
||||
#import "src/schema.typ"
|
||||
#import "docs/examples.typ"
|
||||
@ -26,23 +28,215 @@
|
||||
link(label(label-name))[#display-name]
|
||||
}
|
||||
|
||||
#let note(it) = showybox(
|
||||
title: "Note",
|
||||
title-style: (
|
||||
color: white,
|
||||
weight: "bold"
|
||||
),
|
||||
frame: (
|
||||
title-color: blue.lighten(30%),
|
||||
border-color: blue.darken(40%)
|
||||
),
|
||||
it
|
||||
)
|
||||
|
||||
#show link: set text(blue)
|
||||
|
||||
= Introduction
|
||||
|
||||
This package provides a way to make beautiful register diagrams using the CeTZ package. It can be used to document Assembly instructions or binary registers
|
||||
|
||||
This is a port of the #link("https://git.kb28.ch/HEL/rivet")[homonymous Python script] for Typst. For more information on the schema format, please check out the original project's #link("https://git.kb28.ch/HEL/rivet/src/branch/main/format.md")[format.md]
|
||||
This is a port of the #link("https://git.kb28.ch/HEL/rivet")[homonymous Python script] for Typst.
|
||||
|
||||
= Usage
|
||||
|
||||
Simply import `schema` from #link("src/lib.typ") and call `schema.load` to parse a schema description. Then use `schema.render` to render it, et voilà !
|
||||
#pad(left: 1em)[```typ
|
||||
#import "src/lib.typ": schema
|
||||
#import "@preview/rivet:0.1.0": schema
|
||||
#let doc = schema.load("path/to/schema.yaml")
|
||||
#schema.render(doc)
|
||||
```]
|
||||
|
||||
= Format
|
||||
|
||||
This section describes the structure of a schema definition. The examples given use the JSON syntax. For examples in different formats, see #link("https://git.kb28.ch/HEL/rivet-typst/src/branch/main/gallery/test.yaml")[test.yaml], #link("https://git.kb28.ch/HEL/rivet-typst/src/branch/main/gallery/test.json")[test.json] and #link("https://git.kb28.ch/HEL/rivet-typst/src/branch/main/gallery/test.xml")[test.xml]. You can also directly define a schema using Typst dictionaries and arrays.
|
||||
|
||||
Since the XML format is quite different from the other, you might find it helpful to look at the examples on GitHub to get familiar with it.
|
||||
|
||||
== Main layout
|
||||
|
||||
A schema contains a dictionary of structures. The must be at least one defined structure named "main".
|
||||
|
||||
It can also optionnaly contain a "colors" dictionary. More details about this in #link(<format-colors>)[Colors]
|
||||
|
||||
#sourcecode[```json
|
||||
{
|
||||
"structures": {
|
||||
"main": {
|
||||
...
|
||||
},
|
||||
"struct1": {
|
||||
...
|
||||
},
|
||||
"struct2": {
|
||||
...
|
||||
},
|
||||
...
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
#pagebreak(weak: true)
|
||||
|
||||
== Structure <format-structure>
|
||||
|
||||
A structure has a given number of bits and one or multiple ranges. Each range of bits can have a name, a description and / or values with special meaning (see #link(<format-range>)[Range]). A range's structure can also depend on another range's value (see #link(<format-dependencies>)[Dependencies]).
|
||||
|
||||
The range name (or key) defines the left- and rightmost bits (e.g. `7-4` goes from bit 7 down to bit 4). Bits are displayed in big-endian, i.e. the leftmost bit has the highest value.
|
||||
|
||||
#sourcecode[```json
|
||||
"main": {
|
||||
"bits": 8,
|
||||
"ranges": {
|
||||
"7-4": {
|
||||
...
|
||||
},
|
||||
"3-2": {
|
||||
...
|
||||
},
|
||||
"1": {
|
||||
...
|
||||
},
|
||||
"0": {
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
== Range <format-range>
|
||||
|
||||
A range represents a group of consecutive bits. It can have a name (displayed in the bit cells), a description (displayed under the structure) and / or values.
|
||||
|
||||
For values depending on other ranges, see #link(<format-dependencies>)[Dependencies].
|
||||
|
||||
#note[
|
||||
In YAML, make sure to wrap values in quotes because some values can be interpreted as octal notation (e.g. 010 #sym.arrow.r 8)
|
||||
]
|
||||
|
||||
#sourcecode[```json
|
||||
"3-2": {
|
||||
"name": "op",
|
||||
"description": "Logical operation",
|
||||
"values": {
|
||||
"00": "AND",
|
||||
"01": "OR",
|
||||
"10": "XOR",
|
||||
"11": "NAND"
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
#pagebreak(weak: true)
|
||||
|
||||
== Dependencies <format-dependencies>
|
||||
|
||||
The structure of one range may depend on the value of another. To represent this situation, first indicate on the child range the range on which it depends.
|
||||
|
||||
Then, in its values, indicate which structure to use. A description can also be added (displayed above the horizontal dependency arrow)
|
||||
|
||||
#sourcecode[```json
|
||||
"7-4": {
|
||||
...
|
||||
"depends-on": "0",
|
||||
"values": {
|
||||
"0": {
|
||||
"description": "immediate value",
|
||||
"structure": "immediateValue"
|
||||
},
|
||||
"1": {
|
||||
"description": "value in register",
|
||||
"structure": "registerValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
Finally, add the sub-structures to the structure dictionary:
|
||||
|
||||
#sourcecode[```json
|
||||
{
|
||||
"structures": {
|
||||
"main": {
|
||||
...
|
||||
},
|
||||
"immediateValue": {
|
||||
"bits": 4,
|
||||
...
|
||||
},
|
||||
"registerValue": {
|
||||
"bits": 4,
|
||||
...
|
||||
},
|
||||
...
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
#pagebreak(weak: true)
|
||||
|
||||
== Colors <format-colors>
|
||||
|
||||
You may want to highlight some ranges to make your diagram more readable. For this, you can use colors. Colors may be defined in a separate dictionary, at the same level as the "structures" dictionary:
|
||||
|
||||
#sourcecode[```json
|
||||
{
|
||||
"structures": {
|
||||
...
|
||||
},
|
||||
"colors": {
|
||||
...
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
It can contain color definitions for any number of ranges. For each range, you may then define a dictionary mapping bit ranges to a particular color:
|
||||
|
||||
#sourcecode[```json
|
||||
"colors": {
|
||||
"main": {
|
||||
"31-28": "#ABCDEF",
|
||||
"27-20": "12,34,56"
|
||||
},
|
||||
"registerValue": {
|
||||
"19-10": [12, 34, 56]
|
||||
}
|
||||
}
|
||||
```]
|
||||
|
||||
Valid color formats are:
|
||||
- hex string starting with `#`, e.g. `"#23fa78"`
|
||||
- array of three integers (only JSON, YAML and Typst), e.g. `[35, 250, 120]`
|
||||
- string of three comma-separated integers (useful for XML), e.g. `"35,250,120"`
|
||||
- a Typst color (only Typst), e.g. `colors.green` or `rgb(35, 250, 120)`
|
||||
|
||||
#note[
|
||||
The XML format implements colors a bit differently. Instead of having a "colors" dictionary, color definitions are directly put on the same level as structure definitions. For this, you can use a `color` node with the attributes "structure", "color", "start" and "end", like so:
|
||||
#sourcecode[```xml
|
||||
<schema>
|
||||
<structure id="main" bits="8">
|
||||
...
|
||||
</structure>
|
||||
...
|
||||
<color structure="main" color="#FF0000" start="4" end="7" />
|
||||
<color structure="main" color="255,0,0" start="0" end="3" />
|
||||
</schema>
|
||||
```]
|
||||
]
|
||||
|
||||
#pagebreak(weak: true)
|
||||
|
||||
= Config presets
|
||||
|
||||
Aside from the default config, some example presets are also provided:
|
||||
|
@ -1,4 +1,4 @@
|
||||
#let version = version((0,0,2))
|
||||
#let version = version(0,1,0)
|
||||
|
||||
#import "config.typ"
|
||||
#import "schema.typ"
|
@ -50,6 +50,28 @@
|
||||
parse-raw(path-or-schema)
|
||||
}
|
||||
|
||||
if "colors" in schema {
|
||||
for struct in schema.colors.keys() {
|
||||
for (span, col) in schema.colors.at(struct) {
|
||||
if type(col) == str {
|
||||
if col.starts-with("#") {
|
||||
col = rgb(col)
|
||||
} else {
|
||||
let (r, g, b) = col.split(",").map(v => int(v))
|
||||
col = rgb(r, g, b)
|
||||
}
|
||||
} else if type(col) == array {
|
||||
col = rgb(..col)
|
||||
} else if type(col) != color {
|
||||
panic("Invalid color format")
|
||||
}
|
||||
schema.colors.at(struct).at(span) = col
|
||||
}
|
||||
}
|
||||
} else {
|
||||
schema.insert("colors", (:))
|
||||
}
|
||||
|
||||
let structures = (:)
|
||||
for (id, data) in schema.structures {
|
||||
id = str(id)
|
||||
|
@ -83,8 +83,10 @@
|
||||
|
||||
#let parse(content) = {
|
||||
let struct-elmts = content.children.filter(e => "tag" in e and e.tag == "structure")
|
||||
let color-elmts = content.children.filter(e => "tag" in e and e.tag == "color")
|
||||
|
||||
let structures = (:)
|
||||
let colors = (:)
|
||||
|
||||
for struct-elmt in struct-elmts {
|
||||
structures.insert(
|
||||
@ -93,8 +95,19 @@
|
||||
)
|
||||
}
|
||||
|
||||
for color-elmt in color-elmts {
|
||||
let struct = color-elmt.attrs.structure
|
||||
if not struct in colors {
|
||||
colors.insert(struct, (:))
|
||||
}
|
||||
|
||||
let span = color-elmt.attrs.end + "-" + color-elmt.attrs.start
|
||||
colors.at(struct).insert(span, color-elmt.attrs.color)
|
||||
}
|
||||
|
||||
return (
|
||||
structures: structures
|
||||
structures: structures,
|
||||
colors: colors
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rivet"
|
||||
version = "0.0.2"
|
||||
version = "0.1.0"
|
||||
compiler = "0.11.0"
|
||||
repository = "https://git.kb28.ch/HEL/rivet-typst"
|
||||
entrypoint = "src/lib.typ"
|
||||
@ -11,4 +11,4 @@ categories = [ "visualization" ]
|
||||
license = "Apache-2.0"
|
||||
description = "Register / Instruction Visualizer & Explainer Tool with Typst, using CeTZ"
|
||||
keywords = [ "assembly", "instruction", "binary" ]
|
||||
exclude = [ "/gallery/*" ]
|
||||
exclude = [ "gallery", "gallery.bash", "docs" ]
|
Reference in New Issue
Block a user