Skip to content

Commit a8e71db

Browse files
committed
Expose DIP pin names in SVG and legends
1 parent f085e9d commit a8e71db

5 files changed

Lines changed: 30 additions & 3 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Export printable assembly guides with bills of materials and staged diagrams.
66
- Exclude nonphysical annotation wires from assembly guides and live reload watched HTML after successful changes.
77
- Highlight the exact wire routes reported by short-circuit annotations.
8+
- Show DIP functional pin names in SVG hover titles and optional printed legends.
89
- Show rail-mounted parts as logical edge pin maps at their declared rail holes.
910
- Allow validated custom color palettes and embedded fonts in breadboard output.
1011
- Resolve named switch states directly and reject HTML viewers that exceed the 256-state budget.

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ across `--step` images. The breadboard and netlist views accept v2 JSON IR.
239239
- The built-in TO-92 transistors, trimmer potentiometer, `sc56_11ewa`
240240
seven-segment display, and `wp154a4sureqbfzgc` RGB LED have dedicated
241241
diagram shapes.
242+
- DIP pin numbers show functional names on hover. Add `--legend` to print a
243+
readable pin map below the board, such as `1 GND · 2 TRIG` for an NE555.
242244
- Occupied holes and connected holes have different markers. LED colors accept
243245
CSS names and hexadecimal values such as `#6d5af0`. Hover over an occupied
244246
or connected hole in the SVG to see its hole ID and net.

‎lib/breadkit/render/svg_renderer.rb‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,9 @@ def dip_svg(component, pins)
524524
fill: "none", stroke: @colors[:dip_notch], stroke_width: 0.8)
525525
pins.each do |pin, hole|
526526
display = display_hole(hole)
527-
out << text(px(display.x), py(display.y) + (display.y > 4 ? 4 : -2), pin.number, "font-size" => 3.5, "text-anchor" => "middle")
527+
number = text(px(display.x), py(display.y) + (display.y > 4 ? 4 : -2), pin.number,
528+
"font-size" => 3.5, "text-anchor" => "middle")
529+
out << %(<g data-dip-pin="#{escape(component.ref)}.#{escape(pin.name)}"><title>Pin #{escape(pin.number)}: #{escape(pin.name)}</title>#{number}</g>)
528530
end
529531
out.join
530532
end
@@ -1005,6 +1007,11 @@ def legend_svg
10051007
out << text(x + 15, y, net.name, "font-size" => 5.5)
10061008
y += 9
10071009
end
1010+
dip_pin_map_lines.each do |pin_line|
1011+
out << text(x, y, pin_line, "font-size" => 5.5)
1012+
y += 7
1013+
end
1014+
y += 2 unless dip_pin_map_lines.empty?
10081015
end
10091016
@annotations.each_with_index do |item, index|
10101017
message = read(item, "message") || read(item, "rule")
@@ -1045,6 +1052,13 @@ def legend_nets
10451052
@nets.select { |net| visible_net?(net) && !(net.members.length == 1 && net.holes.empty?) }
10461053
end
10471054

1055+
def dip_pin_map_lines
1056+
@visible_components.select { |component| component.part.data.dig("render", "shape") == "dip" }.flat_map do |component|
1057+
names = component.pins.values.sort_by { |pin| pin.number.to_i }.map { |pin| "#{pin.number} #{pin.name}" }
1058+
annotation_lines("#{component.ref} pins: #{names.join(' · ')}")
1059+
end
1060+
end
1061+
10481062
def annotations_svg
10491063
badge_counts = Hash.new(0)
10501064
@annotations.each_with_index.map do |item, index|
@@ -1247,7 +1261,7 @@ def view_box(mode)
12471261
def legend_height
12481262
return 0 unless @legend_enabled || !@annotations.empty?
12491263

1250-
20 + (@legend_enabled ? legend_nets.length * 9 : 0) +
1264+
20 + (@legend_enabled ? legend_nets.length * 9 + dip_pin_map_lines.length * 7 + (dip_pin_map_lines.empty? ? 0 : 2) : 0) +
12511265
@annotations.each_with_index.sum { |item, index| annotation_lines("#{index + 1}. #{read(item, "message") || read(item, "rule")}").length * 7 + 2 }
12521266
end
12531267

‎spec/breadkit/render_spec.rb‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@
9898
expect(REXML::XPath.match(document, "//g[@data-ref='RGB1']//*[@data-channel]").map { |node| node.attributes["data-channel"] }).to eq(%w[R G B])
9999
end
100100

101+
it "shows DIP functional pin names on hover and in the optional legend" do
102+
input = File.expand_path("../../../breadkit/examples/02_555_blinker.bk.rb", __dir__)
103+
document = REXML::Document.new(described_class.new.render(Breadkit.load(input), legend: true, orientation: "landscape"))
104+
pins = REXML::XPath.match(document, "//g[@id='components']//g[@data-ref='U1']//g[@data-dip-pin]")
105+
expect(pins.length).to eq(8)
106+
expect(pins.map { |pin| pin.elements["title"].text }).to include("Pin 1: GND", "Pin 2: TRIG", "Pin 4: RESET", "Pin 8: VCC")
107+
legend = REXML::XPath.match(document, "//g[@id='legend']//text").map(&:text).join(" ")
108+
expect(legend).to include("U1 pins:", "1 GND", "2 TRIG", "8 VCC")
109+
end
110+
101111
it "draws TO-92 transistor and trimmer potentiometer bodies" do
102112
builder = Breadkit::DSL::Builder.new
103113
builder.instance_eval('board :mini; transistor :Q1, "BC547", pins: %w[a1 a2 a3]; pot :RV1, at: "a7"', "bodies.bk.rb", 1)

‎spec/snapshots/02_555_blinker.svg‎

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)