diff --git a/gallery/target_api.pdf b/gallery/target_api.pdf index e56479d..840b756 100644 Binary files a/gallery/target_api.pdf and b/gallery/target_api.pdf differ diff --git a/gallery/target_api.typ b/gallery/target_api.typ index 991caf9..6b810ef 100644 --- a/gallery/target_api.typ +++ b/gallery/target_api.typ @@ -13,25 +13,11 @@ ), debug: (ports: true) ) - - element.block( - size: (1, 2), - ports: ( - west: (("a", "A"), "e"), - north: "b", - east: "c", - south: "d" - ), - pos: ( - (offset: -1, from: "PCBuf.south"), - 2,//(align: "e", with: "PCBuf.EN"), - ) - ) - /* wire.stub("PCBuf.CLK", name: "CLK") wire.stub("PCBuf.EN", name: "PCWrite") + /* element.multiplexer( pos: ( 3, (align: "in0", with: "PCBuf.PC") diff --git a/src/util.typ b/src/util.typ index a444434..037ae67 100644 --- a/src/util.typ +++ b/src/util.typ @@ -73,4 +73,15 @@ #let valid-anchors = ( "center", "north", "east", "west", "south", "north-east", "north-west", "south-east", "south-west" -) \ No newline at end of file +) + +#let get-port-side(element, port) = { + for (side, ports) in element.ports { + for p in ports { + if p.id == port { + return side + } + } + } + panic("Unknown port " + port + " on element " + element.id) +} \ No newline at end of file diff --git a/src/wire.typ b/src/wire.typ index 8300a2c..661faed 100644 --- a/src/wire.typ +++ b/src/wire.typ @@ -1,5 +1,6 @@ #import "@preview/cetz:0.3.2": draw, coordinate -#import "util.typ": opposite-anchor +#import "util.typ": opposite-anchor, get-port-side +#import "elements/element.typ" /// List of valid wire styles /// #examples.wires @@ -267,40 +268,70 @@ /// - vertical (bool): Whether the name should be displayed vertically /// - length (number): The length of the stub /// - name-offset (number): The name offset, perpendicular to the stub -#let stub(port-id, side, name: none, vertical: false, length: 1em, name-offset: 0) = { - let end-offset = ( - north: (0, length), - east: (length, 0), - south: (0, -length), - west: (-length, 0) - ).at(side) - - let name-offset = ( - north: (name-offset, length), - east: (length, name-offset), - south: (name-offset, -length), - west: (-length, name-offset) - ).at(side) - - draw.line( - port-id, - (rel: end-offset, to: port-id) - ) - if name != none { - let text-anchor = if vertical { - ( - "north": "west", - "south": "east", - "west": "south", - "east": "north" - ).at(side) - } else { opposite-anchor(side) } - draw.content( - anchor: text-anchor, - padding: 0.2em, - angle: if vertical {90deg} else {0deg}, - (rel: name-offset, to: port-id), - name - ) +#let stub(anchor, name: none, vertical: false, length: 1em, name-offset: 0) = { + if "." not in anchor { + panic("`anchor` must be a valid anchor of an element") } + let parts = anchor.split(".") + let port-id = parts.last() + let port-elmt-id = parts.slice(0, -1).join(".") + + let pre-process = (elements, elmt) => { + let eid = elmt.id + + if port-elmt-id not in elements { + panic("Unknown element " + port-elmt-id) + } + let port-elmt = elements.at(port-elmt-id) + let side = get-port-side(port-elmt, port-id) + elements.at(eid).insert("side", side) + return elements + } + + let draw-func(elmt, bounds) = { + let side = elmt.side + let end-offset = ( + north: (0, length), + east: (length, 0), + south: (0, -length), + west: (-length, 0) + ).at(side) + + let name-offset = ( + north: (name-offset, length), + east: (length, name-offset), + south: (name-offset, -length), + west: (-length, name-offset) + ).at(side) + + let shapes = () + shapes += draw.line( + anchor, + (rel: end-offset, to: anchor) + ) + if name != none { + let text-anchor = if vertical { + ( + "north": "west", + "south": "east", + "west": "south", + "east": "north" + ).at(side) + } else { opposite-anchor(side) } + shapes += draw.content( + anchor: text-anchor, + padding: 0.2em, + angle: if vertical {90deg} else {0deg}, + (rel: name-offset, to: anchor), + name + ) + } + + return (shapes, bounds) + } + + return element.elmt( + draw-shape: draw-func, + pre-process: pre-process + ) } \ No newline at end of file