diff --git a/doc/example.typ b/doc/example.typ new file mode 100644 index 0000000..0ff4bac --- /dev/null +++ b/doc/example.typ @@ -0,0 +1,41 @@ +#import "@preview/cetz:0.2.2": draw +#import "../src/circuit.typ": circuit +#import "../src/util.typ" + +#let example-preamble = "import \"../src/lib.typ\": *;" +#let example-scope = ( + draw: draw +) + +#let example(src, show-src: true, vertical: false, fill: true) = { + src = src.text + let full-src = example-preamble + src + let body = eval(full-src, scope: example-scope) + let img = circuit(length: 2em, body) + + block(width: 100%, + align(center, + box( + stroke: black + 1pt, + radius: .5em, + fill: if fill {util.colors.yellow.lighten(80%)} else {none}, + if show-src { + let src-block = align(left, raw(src, lang: "typc")) + table( + columns: if vertical {1} else {2}, + inset: 1em, + align: horizon + center, + stroke: none, + img, + if vertical {table.hline()} else {table.vline()}, src-block + ) + } else { + table( + inset: 1em, + img + ) + } + ) + ) + ) +} \ No newline at end of file diff --git a/doc/examples.typ b/doc/examples.typ new file mode 100644 index 0000000..a38df0d --- /dev/null +++ b/doc/examples.typ @@ -0,0 +1,76 @@ +#import "example.typ": example + +#let alu = example(``` +element.alu(x: 0, y: 0, w: 1, h: 2, id: "alu") +wire.stub("alu-port-in1", "west") +wire.stub("alu-port-in2", "west") +wire.stub("alu-port-out", "east") +```) + +#let block = example(``` +element.block( + x: 0, y: 0, w: 2, h: 2, id: "block", + ports: ( + north: ((id: "clk", clock: true),), + west: ((id: "in1", name: "A"), + (id: "in2", name: "B")), + east: ((id: "out", name: "C"),) + ) +) +wire.stub("block-port-clk", "north") +wire.stub("block-port-in1", "west") +wire.stub("block-port-in2", "west") +wire.stub("block-port-out", "east") +```) + +#let extender = example(``` +element.extender( + x: 0, y: 0, w: 3, h: 1, + id: "extender" +) +wire.stub("extender-port-in", "west") +wire.stub("extender-port-out", "east") +```) + +#let multiplexer = example(``` +element.multiplexer( + x: 0, y: 0, w: 1, h: 3, + id: "multiplexer", + entries: 3 +) +wire.stub("multiplexer.north", "north") +wire.stub("multiplexer-port-out", "east") + +element.multiplexer( + x: 0, y: -4, w: 1, h: 3, + id: "multiplexer2", + entries: ("A", "B", "C") +) +wire.stub("multiplexer2.south", "south") +wire.stub("multiplexer2-port-out", "east") + +for i in range(3) { + wire.stub("multiplexer-port-in" + str(i), "west") + wire.stub("multiplexer2-port-in" + str(i), "west") +} +```) + +#let wires = example(``` +for i in range(3) { + draw.circle((i * 3, 0), radius: .1, name: "p" + str(i * 2)) + draw.circle((i * 3 + 2, 1), radius: .1, name: "p" + str(i * 2 + 1)) + draw.content((i * 3 + 1, -1), raw(wire.wire-styles.at(i))) +} +wire.wire("w1", ("p0", "p1"), style: "direct") +wire.wire("w2", ("p2", "p3"), style: "zigzag") +wire.wire("w3", ("p4", "p5"), style: "dodge", + dodge-y: -0.5, dodge-margins: (0.5, 0.5)) +```, vertical: true) + +#let stub = example(``` +draw.circle((0, 0), radius: .1, name: "p") +wire.stub("p", "north", name: "north", length: 1) +wire.stub("p", "east", name: "east", vertical: true) +wire.stub("p", "south", name: "south", length: 15pt) +wire.stub("p", "west", name: "west", length: 3em) +```) diff --git a/manual.pdf b/manual.pdf index 6d7183f..6d1eb91 100644 Binary files a/manual.pdf and b/manual.pdf differ diff --git a/manual.typ b/manual.typ index a6341f7..99ea598 100644 --- a/manual.typ +++ b/manual.typ @@ -1,16 +1,72 @@ #import "@preview/tidy:0.3.0" #import "@preview/cetz:0.2.2": draw, canvas +#import "src/lib.typ" +#import "doc/examples.typ" #import "src/circuit.typ": circuit #import "src/element.typ" #import "src/util.typ" #import "src/wire.typ" +#set heading(numbering: (..num) => if num.pos().len() < 4 { + numbering("1.1", ..num) +}) +#{ + outline(indent: true, depth: 3) +} +#set page(numbering: "1/1", header: align(right)[circuiteria #sym.dash.em v#lib.version]) +#show link: set text(blue) +#show heading.where(level: 3): it => context { + let cnt = counter(heading) + let i = cnt.get().at(it.depth) - 1 + let color = util.colors.values().at(i) + block(width: 100%)[ + #grid( + columns: (auto, 1fr), + column-gutter: 1em, + align: horizon, + it, + { + place(horizon)[ + #line( + start: (0%, 0%), + end: (100%, 0%), + stroke: color + 1pt + ) + ] + place(horizon)[ + #circle(radius: 3pt, stroke: none, fill: color) + ] + place(horizon+right)[ + #circle(radius: 3pt, stroke: none, fill: color) + ] + } + ) + ] +} + += Introduction + +This package provides a way to make beautiful block circuit diagrams using the CeTZ package. + += Usage + +Simply import #link("src/lib.typ") and call the `circuit` function: +#pad(left: 1em)[```typ +#import "src/lib.typ" +#lib.circuit({ + import lib: * + ... +}) +```] + += Reference + #let circuit-docs = tidy.parse-module( read("src/circuit.typ"), name: "circuit", require-all-parameters: true ) -#tidy.show-module(circuit-docs, style: tidy.styles.minimal) +#tidy.show-module(circuit-docs) #pagebreak() @@ -32,7 +88,12 @@ read("src/wire.typ"), name: "wire", require-all-parameters: true, - scope: (wire: wire, circuit: circuit, draw: draw) + scope: ( + wire: wire, + circuit: circuit, + draw: draw, + examples: examples + ) ) #tidy.show-module(wire-docs) @@ -45,13 +106,14 @@ read("src/elements/extender.typ") + "\n" + read("src/elements/multiplexer.typ"), name: "element", - require-all-parameters: false, + require-all-parameters: true, scope: ( element: element, circuit: circuit, draw: draw, wire: wire, - tidy: tidy + tidy: tidy, + examples: examples ) ) diff --git a/src/circuit.typ b/src/circuit.typ index 13c0f80..4ae8331 100644 --- a/src/circuit.typ +++ b/src/circuit.typ @@ -3,7 +3,7 @@ /// Draws a block circuit diagram /// -/// This function is also available as `circuiteria.circuit()` +/// This function is also available at the package root /// /// - body (none, array, element): A code block in which draw functions have been called /// - length (length, ratio): Optional base unit diff --git a/src/elements/alu.typ b/src/elements/alu.typ index 548ca6c..d15b9d6 100644 --- a/src/elements/alu.typ +++ b/src/elements/alu.typ @@ -39,14 +39,7 @@ /// Draws an ALU with two inputs /// -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// element.alu(x: 0, y: 0, w: 1, h: 2, id: "alu") -/// wire.stub("alu-port-in1", "west") -/// wire.stub("alu-port-in2", "west") -/// wire.stub("alu-port-out", "east") -/// }) -/// ]) +/// #examples.alu /// - x (number, dictionary): see `elmt()` /// - y (number, dictionary): see `elmt()` /// - w (number): see `elmt()` diff --git a/src/elements/block.typ b/src/elements/block.typ index 9431525..bb41fc0 100644 --- a/src/elements/block.typ +++ b/src/elements/block.typ @@ -15,37 +15,15 @@ /// Draws a block element /// -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// element.block( -/// x: 0, y: 0, -/// w: 2, h: 2, -/// id: "block", -/// ports: ( -/// north: ((id: "clk", clock: true),), -/// west: ( -/// (id: "in1", name: "A"), -/// (id: "in2", name: "B"), -/// ), -/// east: ( -/// (id: "out", name: "C"), -/// ) -/// ) -/// ) -/// wire.stub("block-port-clk", "north") -/// wire.stub("block-port-in1", "west") -/// wire.stub("block-port-in2", "west") -/// wire.stub("block-port-out", "east") -/// }) -/// ]) +/// #examples.block /// - x (number, dictionary): see `elmt()` /// - y (number, dictionary): see `elmt()` /// - w (number): see `elmt()` /// - h (number): see `elmt()` /// - name (none, str): see `elmt()` /// - name-anchor (str): see `elmt()` -/// - ports: (dictionary): see `elmt()` -/// - ports-margins: (dictionary): see `elmt()` +/// - ports (dictionary): see `elmt()` +/// - ports-margins (dictionary): see `elmt()` /// - fill (none, color): see `elmt()` /// - stroke (stroke): see `elmt()` /// - id (str): see `elmt()` diff --git a/src/elements/extender.typ b/src/elements/extender.typ index c219ad6..bb789c5 100644 --- a/src/elements/extender.typ +++ b/src/elements/extender.typ @@ -27,17 +27,7 @@ /// Draws a bit extender /// -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// element.extender( -/// x: 0, y: 0, -/// w: 3, h: 1, -/// id: "extender" -/// ) -/// wire.stub("extender-port-in", "west") -/// wire.stub("extender-port-out", "east") -/// }) -/// ]) +/// #examples.extender /// - x (number, dictionary): see `elmt()` /// - y (number, dictionary): see `elmt()` /// - w (number): see `elmt()` diff --git a/src/elements/multiplexer.typ b/src/elements/multiplexer.typ index fd8ee0c..49dad5c 100644 --- a/src/elements/multiplexer.typ +++ b/src/elements/multiplexer.typ @@ -23,32 +23,7 @@ /// Draws a multiplexer /// -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// element.multiplexer( -/// x: 0, y: 0, -/// w: 1, h: 3, -/// id: "multiplexer", -/// entries: 3 -/// ) -/// wire.stub("multiplexer-port-in0", "west") -/// wire.stub("multiplexer-port-in1", "west") -/// wire.stub("multiplexer-port-in2", "west") -/// wire.stub("multiplexer.north", "north") -/// wire.stub("multiplexer-port-out", "east") -/// element.multiplexer( -/// x: 3, y: 0, -/// w: 1, h: 3, -/// id: "multiplexer2", -/// entries: ("A", "B", "C") -/// ) -/// wire.stub("multiplexer2-port-in0", "west") -/// wire.stub("multiplexer2-port-in1", "west") -/// wire.stub("multiplexer2-port-in2", "west") -/// wire.stub("multiplexer2.south", "south") -/// wire.stub("multiplexer2-port-out", "east") -/// }) -/// ]) +/// #examples.multiplexer /// - x (number, dictionary): see `elmt()` /// - y (number, dictionary): see `elmt()` /// - w (number): see `elmt()` diff --git a/src/wire.typ b/src/wire.typ index 4b7ed9c..809fc46 100644 --- a/src/wire.typ +++ b/src/wire.typ @@ -2,22 +2,7 @@ #import "util.typ": opposite-anchor /// List of valid wire styles -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// draw.circle((0, 0), radius: .1, name: "p1") -/// draw.circle((2, 1), radius: .1, name: "p2") -/// draw.circle((3, 0), radius: .1, name: "p3") -/// draw.circle((5, 1), radius: .1, name: "p4") -/// draw.circle((6, 0), radius: .1, name: "p5") -/// draw.circle((8, 1), radius: .1, name: "p6") -/// wire.wire("w1", ("p1", "p2"), style: "direct") -/// wire.wire("w2", ("p3", "p4"), style: "zigzag") -/// wire.wire("w3", ("p5", "p6"), style: "dodge", dodge-y: -0.5, dodge-margins: (0.5, 0.5)) -/// draw.content((1, -1), [`direct`]) -/// draw.content((4, -1), [`zigzag`]) -/// draw.content((7, -1), [`dodge`]) -/// }) -/// ]) +/// #examples.wires #let wire-styles = ("direct", "zigzag", "dodge") #let signal-width = 1pt #let bus-width = 1.5pt @@ -233,13 +218,7 @@ /// Draws a wire stub (useful for unlinked ports) /// -/// #box(width: 100%, align(center)[ -/// #circuit({ -/// draw.circle((0, 0), radius: .1, name: "p") -/// wire.stub("p", "east", name: "port") -/// }) -/// ]) -/// +/// #examples.stub /// - port-id (str): The port anchor /// - side (str): The side on which the port is (one of "north", "east", "south", "west") /// - name (none, str): Optional name displayed at the end of the stub