#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)