Skip to content

fix(pptx): draw inhibition as inhibition, not as activation - #169

Merged
adamjohnwright merged 1 commit into
mainfrom
fix/pptx-arrowheads
Sep 4, 2026
Merged

fix(pptx): draw inhibition as inhibition, not as activation#169
adamjohnwright merged 1 commit into
mainfrom
fix/pptx-arrowheads

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

An adversarial pass over the PowerPoint export shipped earlier today, checked against the diagram it claims to reproduce.

The defect that matters

The shape model had arrow: boolean, and the exporter turned every true into a filled triangle line end. The diagram draws four arrowheads, and three of them mean something a triangle does not:

edge the diagram draws the slide drew
production filled triangle filled triangle
catalysis hollow circle filled triangle
positive regulation hollow triangle, green filled triangle, navy
negative regulation bar across the line, red filled triangle

So a downloaded slide asserted the opposite of the pathway: inhibition read as activation.

OOXML line ends cannot express this — they are always filled, always the line's own colour, and there is no bar among triangle/stealth/diamond/oval/arrow. Arrowheads are now geometry the page computes and the exporter merely spells, the same division everything else here follows.

R-HSA-109606 exports 129 arrowheads: 84 filled triangles, 17 filled circles, 11 hollow circles, 9 hollow triangles, 8 bars. The 8 bars and 20 hollow heads match one-for-one the 8 red and 20 green marks in the site's own SVG.

Framed exports put shapes off the slide

Keeping a glyph that crosses the frame is right; keeping the parts that fall outside is not. An SVG has a viewBox and never draws them — a slide has nothing of the sort, so a connector spanning the diagram arrived as an object 31 inches off the side of an 11 inch slide.

Connectors are clipped per segment, so one crossing the frame twice returns as two runs rather than a line joining them through the middle. Glyph boxes are clipped with them, and an arrowhead is drawn only where the end it marks is in view. Both fixtures now assert the invariant that broke: every shape lies inside the extent the page declares. 0 shapes past the slide edge, from 17 of 40.

Smaller

  • A text run keeps its alpha.
  • A filled shape with no border no longer asks for a zero-width outline, which PowerPoint draws as a hairline — on a 16px arrowhead, most of the arrowhead.
  • RENDER_CACHE_KEY → v5. v4 was published this morning and the output changed again.

Not defects, though they looked like ones

  • The analysis overlay is carried in full. Every colour a run adds is exported; the missing-colour list is identical with and without a token.
  • The 69 greys the SVG "draws" and the slide does not all have fill-opacity="0". The instrument that found them ignored opacity.

Still not carried

Node decorations drawn with background-image (a complex loses the band marking it as one), and rounded corners on round-segments edges. Both noted on #167.

Verified

Full preflight green. 55 unit assertions in tools/render/pptx.spec.mjs, driven by two payloads captured from the running page. Downloaded through Apache as a curator gets it: 765 shapes, 0 pictures, 0 line ends, 8 red and 20 green marks.

Refs #167

An adversarial pass over yesterday's PowerPoint work, against the diagram
it claims to reproduce.

**Arrowheads carried no meaning.** The model had `arrow: boolean` and the
exporter turned every true into a filled triangle line end. The diagram
draws four heads and three of them say something a triangle does not:
catalysis is a hollow circle, positive regulation a hollow green triangle,
and negative regulation a bar across the line. So a slide drew inhibition
as activation -- a figure asserting the opposite of the pathway.

OOXML line ends cannot fix this: they are always filled, always the line's
own colour, and there is no bar among them. Arrowheads are now geometry the
page computes and the exporter merely spells, which is the same division
everything else here follows. R-HSA-109606 exports 129 of them: 84 filled
triangles, 17 filled circles, 11 hollow circles, 9 hollow triangles and 8
bars -- and the 8 bars and 20 hollow heads match, one for one, the 8 red
and 20 green marks the site's own SVG draws.

**Framed exports put shapes off the slide.** Keeping a glyph that crosses
the frame is right; keeping the parts of it that fall outside is not. An
SVG has a viewBox and never draws them; a slide has nothing of the sort, so
a connector spanning the diagram arrived as an object 31 inches off the
side of an 11 inch slide. Connectors are now clipped to the frame -- per
segment, so one crossing the frame twice comes back as two runs rather than
a line joining them through the middle -- glyph boxes are clipped with
them, and an arrowhead is drawn only where the end it marks is in view.
Both fixtures now assert the invariant that broke: every shape lies inside
the extent the page declares.

Also: a text run keeps its alpha, and a filled shape with no border no
longer asks for a zero-width outline, which PowerPoint draws as a hairline
-- on a 16px arrowhead that is most of the arrowhead.

RENDER_CACHE_KEY goes to v5. v4 was published this morning and the output
has changed again; the second time in one day that a correct build served
a stale file, so the note about it now says to treat the key as part of the
change.

Not defects, though they looked like ones on the way past: the analysis
overlay is carried in full -- the colours a run adds are all exported --
and the 69 greys the SVG "draws" and the slide does not carry every one
have fill-opacity="0". The instrument that found them ignored opacity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright enabled auto-merge (squash) September 4, 2026 20:59
@adamjohnwright
adamjohnwright merged commit b326169 into main Sep 4, 2026
6 checks passed
@adamjohnwright
adamjohnwright deleted the fix/pptx-arrowheads branch September 4, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant