Skip to content

ivaquero/consketcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Consketcher

Consketcher is a Typst package for drawing control-system sketches with fletcher.

It provides:

  • ready-to-use block and control-system templates
  • reusable nodes, labels, junctions, and edge helpers
  • small utilities for Chinese labels and automatic spacing

Installation

If you are using a published release, import it from @preview:

#import "@preview/consketcher:0.2.0": *

For local development, import it from @local:

#import "@local/consketcher:0.1.0": *

Quick Start

Open-loop block

#block-open(
  transfer: $G(s)$,
  input: $R(s)$,
  output: $Y(s)$,
)

Closed-loop block

#block-closed(
  transfer: $D(s)G(s)$,
  transfer2: $H(s)$,
  input: $V(s)-X(s)H(s)$,
  output: $X(s)$,
  output2: $X(s)H(s)$,
  loss: "Loss",
  reference: $V(s)$,
)

Closed-loop control system

#sys-closed(
  controler: ctext("控制器"),
  actuator: ctext("执行器"),
  sensor: ctext("传感器"),
  input: ctext("指令信号"),
  output: ctext("执行信号"),
  output2: ctext("传感信号"),
  loss: ctext("损失函数"),
  reference: ctext("校正信号"),
)

Open-loop example

Closed-loop example

For complete examples, see examples/example.typ.

API Overview

Consketcher exports everything from 0.1.0/src/lib.typ.

The public API is organized into a few focused modules:

  • src/charts.typ: high-level block and control-system templates
  • src/nodes.typ: nodes, labels, references, and marker helpers
  • src/edges.typ: connectors, arrows, and feedback paths
  • src/utils.typ: text helpers and automatic spacing utilities
  • src/components.typ: compatibility barrel that re-exports nodes.typ and edges.typ

In other words, lib.typ is the entrypoint, charts.typ is where the ready-made diagrams live, and the lower-level drawing primitives are split by responsibility into nodes.typ and edges.typ.

Diagram Templates

These are the highest-level entry points.

#block-open(
  transfer: none,
  input: none,
  output: none,
  width: 2,
  height: 2em,
  line: -2,
  start: 1,
  node-maker: rnode,
  edge-maker: arrow,
)
#block-closed(
  transfer: none,
  transfer2: none,
  input: none,
  output: none,
  output2: none,
  loss: none,
  reference: none,
  line: 0.5,
  start: 1,
  reference-gap: auto,
  input-gap: auto,
  feedback-height: 1.25,
  label-size: 0.6em,
  node-maker: rnode,
  ref-maker: reference,
  edge-maker: arrow,
  feedback-edge-maker: uturn-v,
)
#sys-open(
  controler: none,
  actuator: none,
  process: none,
  input: none,
  output: none,
  output2: none,
  output3: none,
  subunit: none,
  line: -2,
  start: -2,
  node-maker: rnode,
  edge-maker: arrow,
  boundary-edge-maker: uturn,
  label-maker: label,
)
#sys-closed(
  controler: none,
  actuator: none,
  sensor: none,
  input: none,
  output: none,
  output2: none,
  loss: none,
  reference: none,
  line: 0.5,
  start: 1,
  feedback-height: 1.25,
  node-maker: rnode,
  ref-maker: reference,
  edge-maker: arrow,
)

Legacy high-level helpers are also exported:

#closed-loop-block(plant)

#compensated-loop-block(
  first,
  second,
  third,
  first-width: 5em,
  second-width: 2em,
  third-width: 6em,
)

Layout and Text Utilities

#control-diagram(
  spacing: (1.5em, 1.5em),
  node-stroke: 1pt,
  mark-scale: 80%,
  ..body,
)

#ctext(label, size: 0.8em, font: "Songti SC", ..options)

#edge-label(body, size: 0.6em, ..options)

#label-length(body, fallback: 1)

#auto-gap(body, scale: 1, fallback: 1)

ctext is a convenience wrapper around text(...) with a Chinese-friendly default font. label-length and auto-gap are useful when you want custom diagram templates to adapt spacing to label content.

Nodes and Markers

#rnode(sym, label, shape: rect, height: 2em, corner-radius: 4pt, ..options)

#onode(sym, label, shape: circle, height: 1em, radius: 10pt, ..options)

#gain-node(
  sym,
  label,
  dir: left,
  width: 4em,
  height: 4em,
  fit: 0.8,
  ..options,
)

#formula-node(sym, body, width: 8em, height: 3em, ..options)

#label(sym, body, stroke: none, ..options)

#signed-node(
  sym,
  signs: (),
  node-maker: onode,
  label-maker: label,
  ..node-options,
)

#reference(
  sym,
  x-sign: "+",
  y-sign: "-",
  x-offset: -0.3,
  y-offset: 0.3,
  loss: none,
  loss-offset: -0.5,
  ..options,
)

#reference3(
  sym,
  x: "+",
  top: "+",
  bottom: "+",
  x-offset: -0.25,
  top-offset: -0.25,
  bottom-offset: 0.25,
  radius: 1.35em,
  node-maker: onode,
  label-maker: label,
  ..node-options,
)

#dashed-box(
  enclose,
  stroke: (thickness: 0.5pt, dash: "dashed"),
  inset: 1.5em,
  fill: none,
  corner-radius: 4pt,
  ..options,
)

Edges

#connector(
  n1,
  n2,
  marks: "-",
  label: none,
  label-pos: 0.5,
  label-side: left,
  corner: none,
  corner-radius: 4pt,
  ..options,
)

#arrow(
  n1,
  n2,
  label,
  marks: none,
  label-pos: 0.5,
  label-side: left,
  dashed: false,
  corner: none,
  corner-radius: none,
  ..options,
)

#segment(
  n1,
  n2,
  label,
  marks: none,
  label-pos: 0.5,
  label-side: left,
  dashed: false,
  corner: none,
  corner-radius: none,
  ..options,
)

#uturn(
  n1,
  n2,
  label,
  label-pos: 0.15,
  label-side: left,
  marks: "-|>",
  height: 1.25,
  corner: right,
  corner-radius: 4pt,
  ..options,
)

#uturn2(
  n1,
  n2,
  label,
  label-pos: 0.15,
  label-side: left,
  marks: "-|>",
  height: 1.25,
  corner: right,
  corner-radius: 4pt,
  offset: 1,
  ..options,
)

#uturn-v(
  n1,
  n2,
  label,
  label-pos: 0.15,
  label-side: left,
  marks: "-|>",
  height: 2.5,
  corner: right,
  corner-radius: 4pt,
  ..options,
)

#uturn2-v(
  n1,
  n2,
  label,
  label-pos: 0.15,
  label-side: left,
  marks: "-|>",
  height: 2.5,
  corner: right,
  corner-radius: 4pt,
  offset: 1,
  ..options,
)

Customization

The template functions are composable. You can pass custom maker functions to change how nodes, references, or edges are drawn. This is the main extension point when you want the built-in layouts but different visual styling.

#let thick-arrow(n1, n2, body, ..options) = arrow(
  n1,
  n2,
  body,
  stroke: 1.5pt,
  ..options,
)

#block-open(
  transfer: $G(s)$,
  input: $u$,
  output: $y$,
  edge-maker: thick-arrow,
)

For closed-loop diagrams, you can also replace the summing-junction maker through ref-maker.

Repository Layout

  • 0.1.0/src/lib.typ: package entrypoint and export hub
  • 0.1.0/src/charts.typ: ready-made block and control-system templates
  • 0.1.0/src/components.typ: compatibility barrel that re-exports drawing helpers
  • 0.1.0/src/nodes.typ: nodes, labels, references, and marker helpers
  • 0.1.0/src/edges.typ: connectors, arrows, and feedback paths
  • 0.1.0/src/utils.typ: text helpers and spacing helpers
  • examples/example.typ: usage examples
  • examples/example.png and examples/example2.png: rendered example previews
  • articles/lib.pdf: generated API reference preview

Local Development

To use the package from @local, clone the repository into your local Typst package workspace:

  • Linux:
    • $XDG_DATA_HOME/typst/packages/local
    • ~/.local/share/typst/packages/local
  • macOS: ~/Library/Application Support/typst/packages/local
  • Windows: %APPDATA%/typst/packages/local

Then clone the repository as consketcher:

git clone https://github.com/ivaquero/typst-consketcher consketcher

and import it with:

#import "@local/consketcher:0.1.0": *

If you are editing the package itself, the most common workflow is:

  1. Put new reusable graph primitives in nodes.typ or edges.typ.
  2. Put new ready-made control-diagram layouts in charts.typ.
  3. Re-export only stable public entry points through lib.typ.
  4. Keep components.typ as a compatibility layer instead of growing it with new logic.

About

Draws Control Blocks using CeTZ (still a toy)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages