All checks were successful
Build Typst PDFs (Docker) / build-typst (push) Successful in 19s
62 lines
2.3 KiB
Typst
62 lines
2.3 KiB
Typst
#import "@preview/zap:0.5.0": *
|
|
#import "@preview/cetz:0.4.2": (
|
|
draw.anchor, draw.arc-through, draw.circle, draw.content, draw.line, draw.rect, draw.rotate, draw.get-ctx, draw.bezier
|
|
)
|
|
|
|
#let logic(name, node, text: $"&"$, invert: false, mirror: false, invert-inputs: (), angle: 0deg, inputs: 2, ..params) = {
|
|
assert(inputs >= 1, message: "logic supports minimum one inputs")
|
|
|
|
let style = (
|
|
width: 0.7,
|
|
min-height: 0.9,
|
|
spacing: 0.4,
|
|
padding: 0.25,
|
|
fill: white,
|
|
stroke: auto,
|
|
)
|
|
|
|
// Drawing function
|
|
let draw(ctx, position, _) = {
|
|
rotate(angle)
|
|
|
|
let height = calc.max(style.min-height, (inputs - 1) * style.spacing + 2 * style.padding)
|
|
let width = style.width * if mirror { -1 } else { 1 }
|
|
|
|
interface((-width / 2, -height / 2), (width / 2, height / 2), io: false)
|
|
|
|
rect((-width / 2, -height / 2), (rel: (width, height)), fill: style.fill, stroke: style.stroke)
|
|
content((0, height / 2 - style.padding / 2), text, anchor: "north", angle: angle)
|
|
|
|
let ball-radius = calc.min(height, width) * 0.1
|
|
|
|
for input in range(1, inputs + 1) {
|
|
let pad = (height - (inputs - 1) * style.spacing) / 2
|
|
let y = height / 2 - pad - (input - 1) * style.spacing;
|
|
|
|
if input in invert-inputs {
|
|
circle((-width / 2 - ball-radius, y), radius: ball-radius, stroke: style.stroke, fill: style.fill)
|
|
anchor("in" + str(input), (-width / 2, y))
|
|
} else {
|
|
anchor("in" + str(input), (-width / 2, y))
|
|
}
|
|
}
|
|
|
|
if invert {
|
|
circle((width / 2 + ball-radius, 0), radius: ball-radius, stroke: style.stroke, fill: style.fill)
|
|
anchor("out", (width / 2, 0))
|
|
} else {
|
|
anchor("out", (width / 2, 0))
|
|
}
|
|
}
|
|
|
|
// Component call
|
|
component("logic", name, node, draw: draw, ..params)
|
|
}
|
|
|
|
#let lnot(name, node, ..params) = logic(name, node, ..params, text: $1$, invert: true)
|
|
#let land(name, node, ..params) = logic(name, node, ..params, text: $"&"$)
|
|
#let lnand(name, node, ..params) = logic(name, node, ..params, text: $"&"$, invert: true)
|
|
#let lor(name, node, ..params) = logic(name, node, ..params, text: $>=1$)
|
|
#let lnor(name, node, ..params) = logic(name, node, ..params, text: $>=1$, invert: true)
|
|
#let lxor(name, node, ..params) = logic(name, node, ..params, text: $=1$)
|
|
#let lxnor(name, node, ..params) = logic(name, node, ..params, text: $=1$, invert: true) |