Bring the free canvas fragments onto one shape - #96
Merged
Merged
Conversation
The content changes in these four are CTG's: each Cyberspace fragment now keeps only the drawn control measure in #main, with the illustrative endpoints and net boxes moved into a hidden example group and the anchor points into the template. That is the shape #78 is about, applied by hand to the three Cyberspace icons. Inkscape rewrites a file wholesale on save - attribute per line, standalone="no", its own namespace declarations, a namedview, an empty defs and a fresh crop of generated ids - so all four needed the normaliser afterwards. It reported 0 refused, which is the guarantee that wanted: the drawn content is byte-for-byte what CTG left, and only the editor's own leavings were taken out. One follow-on belongs with this rather than with the mechanical pass: 60200100's example group carried id="g15", which the normaliser correctly reads as a generated id and drops, leaving the group anonymous. It is given id="example" so it says what it is. Bounds re-measured. 60200100 and 60200200 grew taller, which is CTG's edit - the template's anchor arrows now reach above the drawn measure. Nothing else moved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A free canvas icon holds a <g>#main, a <g>#template, zero or more <g>#example groups, and whatever <defs> the main group needs. That is what almost all of them already were - 545 of 577 - and this brings the stragglers into line so a consumer asking "which element is the content" has one answer rather than four. Three kinds of file were off the shape: - Four put an id straight on a drawing element with no group to hold it: 25218800 and 25281901 on a <polygon id="main">, and 25200600 and 25200700 on a loose <rect>. Each is now wrapped in a <g> carrying that id. - Five define <pattern> elements loose - four at the document root, and two more inside #main itself, where a paint server has no business sitting. They move into a <defs>, which is the one place a definition belongs. - Ordering and ids otherwise left exactly as found. Nothing here changes what is drawn. A <g> carrying only an id paints exactly as its child did, and a <pattern> renders only where something references it - and nothing does: the whole tree holds one live url(#...) reference, 25132000's marker, which is untouched. The issue's note that the pattern files hold the only internal reference is no longer accurate. Verified two independent ways, since SvgFingerprint cannot help here - it records structure, so inserting a group or moving an element changes it by design: - Every drawing primitive compared before and after with its ancestors' attributes folded in, so an added group is invisible to the comparison, and each pattern subtree compared on its own. All nine identical. - FragmentMeasurer re-run over all 577 free canvas icons: every bound unchanged. Left alone deliberately: 26 fragments have no template group at all, which is a question about what those files draw rather than about their shape, and two patterns in 25270400 have no id, so they cannot be referenced from defs either - naming them belongs with the pattern usage work rather than here. Closes #78 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The hidden #474747 rectangle is not part of the construction guide - it is there so the white border of the symbol in #main has something to show up against. The corpus agrees: three fragments carry that backdrop, and the other two, 25200400 and 25200700, both file it under an example group. Id only, so nothing is drawn differently - the rectangle is display="none" in any case, and ids are outside the fingerprint. With this, 551 of 577 free canvas fragments hold only defs/main/template/example*, and every one that does not is simply missing a template. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The README's Details section has been a TBD placeholder for "the internal composition of the SVG files" since the fork. Now that the shape is settled and every fragment holds to it, it can say what it is. A free canvas fragment holds exactly one <g>#main, zero or one <g>#template, zero or more <g>#example, and whatever <defs> main references. The template is optional rather than required, which is the part worth recording because it is a decision rather than an accident. Twenty-six fragments have none, and they divide cleanly: an area measure is defined by at least three control points the user places, so there is no fixed geometry a template could draw - that covers every area without one, Airhead Line included, which is an area despite the name - and the six Space Debris fragments are whole symbols in the way an ordinary icon is, so main holds all of it. Confirmed against both trees: 577 free canvas fragments each, 0 failing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Injecting fragments into the generated classes needs a rule for "which element is the content", and for the free canvas fragments that rule is the shape #78 settled: exactly one <g>#main, zero or one <g>#template, zero or more <g>#example, and whatever <defs> main references. A fragment drifts off it easily - an editor leaves a group anonymous, a new icon arrives with its content loose at the root - and both of those had already happened. Catching it at verify costs nothing; catching it during injection means finding construction scaffolding rendered as though it were the drawing. FragmentShapeChecker reports every fault on a fragment at once, so a file is named once rather than once per thing wrong with it, and points at svg/README.md rather than restating the rule in an error message. Editor metadata is passed over deliberately: FragmentNormaliser's check is bound to the same phase and already fails on it with a message that says what to do, so reporting the same file twice for something that is not about its shape would only be noise. Which icons are free canvas, and which fragment each draws, moves into FreeCanvasIcons. FragmentMeasurer had that derivation inline, its own javadoc citing jmsfx#52 as the caution against duplicating it; a second copy here would have been exactly that mistake. The measurer now shares it and loses the two helpers that went with it. Behaviour-preserving: both models re-measure byte-identical. Bound alongside the normaliser check, taking the directory from the module layout for the same reason - config.yml's resourceDir is an absolute Windows path that resolves nowhere on a runner - and the model from the classpath, which does not have that problem. Verified it can actually fail: renaming one fragment's #main to #content fails the build with "25150100: a group called content; no <g id="main">". 13 unit tests cover it, every case a shape that was genuinely in the tree before this issue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #78.
A free canvas icon holds a
<g>#main, a<g>#template, zero or more<g>#examplegroups, and whatever<defs>the main group needs to render. 545 of 577 already were that. This brings the stragglers into line so a consumer asking "which element is the content" has one answer rather than four.Scoped down from the issue's original three options after discussion: the scaffolding stays in the fragment for now, because
FREE_CANVASicons will need separate handling anyway.Two commits
1 —
Normalise the free canvas fragments edited in Inkscape. The content changes in these four are CTG's: each Cyberspace fragment now keeps only the drawn control measure in#main, with the illustrative endpoints and net boxes moved into a hidden example group and the anchor points into the template. Inkscape rewrites a file wholesale on save, so all four needed the normaliser afterwards — 0 refused, which is the guarantee wanted: the drawn content is byte-for-byte what CTG left, and only the editor's leavings came out.One follow-on belongs with that rather than the mechanical pass:
60200100's example group carriedid="g15", which the normaliser correctly reads as a generated id and drops, leaving it anonymous. It's nowid="example".2 —
Bring the free canvas fragments onto one shape. Nine fragments:25218800,25281901(polygon#main),25200600,25200700(looserect)template2when it is an example25200600<pattern>loose at the root25240301/2/3,25172000,25270400<pattern>inside#mainitself25240301,25270400Patterns move into a
<defs>. Ordering and ids otherwise left exactly as found, with one exception in a third commit:25200600's hidden#474747rectangle is not part of the construction guide but a backdrop for the white border of the symbol in#main, so its group is renamedtemplate2→example. The corpus agrees — three fragments carry that backdrop and the other two,25200400and25200700, both file it under an example group.Nothing changes what is drawn
A
<g>carrying only an id paints exactly as its child did, and a<pattern>renders only where something references it — and nothing does. The whole tree holds one liveurl(#…)reference,25132000's marker, untouched. The issue's note that the pattern files hold the only internal reference is no longer accurate.SvgFingerprintcan't guard this: it records structure, so inserting a group or moving an element changes it by design. Verified two independent ways instead:FragmentMeasurerre-run over all 577 free canvas icons — every bound unchanged. The only bounds that moved in this PR are60200100and60200200, from CTG's edits.mvn verifygreen, Spotless clean.Left alone deliberately
templategroup at all (22 are#mainalone). That's a question about what those files draw, not about their shape.25270400's two patterns have no id, so they can't be referenced fromdefseither. Naming them belongs with the pattern usage work.main + template + example, 13 put example before template. Reordering changes paint order, so it stays out of a "no visual change" pass.After this, 551 of 577 hold only
defs/main/template/example*, and the remaining 26 differ only by a missing template.The matching changes to
jmsfx-halluxare in the hallux working tree, uncommitted.🤖 Generated with Claude Code