| 1 | # Native Hyperlink Specification |
| 2 | |
| 3 | Shared authoring contract for PowerPoint-native click hyperlinks on complete |
| 4 | objects and inline text runs. |
| 5 | |
| 6 | ## 1. Trigger and Ownership |
| 7 | |
| 8 | **Trigger**: A user instruction, source fact, or page plan requires an external |
| 9 | destination or a jump to another slide in the same deck. |
| 10 | |
| 11 | | Layer | Ownership | |
| 12 | |---|---| |
| 13 | | Default Strategist | Record the linked text/object intent and exact target in the applicable §IX page block; never invent or normalize an unknown destination | |
| 14 | | Default Executor | Choose the whole-object or inline carrier and author the canonical SVG anchor | |
| 15 | | Active Quick context | Perform both content and authoring responsibilities directly | |
| 16 | | SVG-to-PPTX exporter | Validate the target, create the native relationship, and attach the click action | |
| 17 | |
| 18 | **Hard rule — page content only**: Hyperlinks are not a confirmation field, |
| 19 | resource, manifest, or `spec_lock.md` entry. Missing or ambiguous targets return |
| 20 | upstream; do not substitute a search result or guessed URL. |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## 2. Canonical SVG |
| 25 | |
| 26 | | Intent | Canonical form | |
| 27 | |---|---| |
| 28 | | Whole object, image, button, or group | `<a href="https://example.com"><g>...</g></a>` | |
| 29 | | Inline text | `<text>Read <a href="https://example.com"><tspan>the guide</tspan></a>.</text>` | |
| 30 | | Same-deck jump | `href="#slide-3"` using the 1-based final slide roster | |
| 31 | | Imported shape-plus-run conflict | Importer-only `data-pptx-shape-hyperlink="..."` on the logical `<g>`, with standard inline anchors retained inside | |
| 32 | |
| 33 | **Hard rule — one target syntax**: Author SVG 2 `href`. Import may read legacy |
| 34 | `xlink:href`, but generated SVG never writes both. Same-deck destinations use |
| 35 | the exact `#slide-N` form and must resolve inside the final roster. External |
| 36 | destinations are absolute URIs with an explicit scheme; percent-encode spaces. |
| 37 | Relative paths, arbitrary fragments, filesystem paths, and `data:`, `file:`, |
| 38 | `javascript:`, or `vbscript:` destinations fail closed. |
| 39 | |
| 40 | **Hard rule — inline run**: Put visible text in one or more `<tspan>` children |
| 41 | inside the anchor. The anchor and its descendants own no `x`, `y`, `dx`, or |
| 42 | `dy`; line positioning belongs to the enclosing line `<tspan>`. A linked inline |
| 43 | formula uses one leaf formula `<tspan>` inside the anchor and retains its native |
| 44 | math contract. |
| 45 | |
| 46 | **Hard rule — whole-object hit area**: Wrap at least one visible SVG element; |
| 47 | do not put direct text or a bare `<tspan>` in a shape anchor. A multi-object |
| 48 | anchor links each exported leaf object. Include an explicit background shape |
| 49 | when gaps inside a button or card must also be clickable. |
| 50 | |
| 51 | Ordinary entrance, emphasis, motion-path, exit, and Morph animation may target |
| 52 | an outer top-level `<g>`. A hyperlink-bearing group cannot also serve as an |
| 53 | interactive `trigger_shape`; use a separate trigger so one click has one owner. |
| 54 | |
| 55 | **Forbidden — ambiguous ownership**: Do not nest `<a>` elements or place an |
| 56 | anchor inside `defs`, metadata, geometry-detail, or a native-replacement |
| 57 | subtree. A complete block formula or native Chart/Table marker may be wrapped |
| 58 | as one whole object; its preview descendants may not contain another anchor. |
| 59 | |
| 60 | **Forbidden — authored transport metadata**: Never author |
| 61 | `data-pptx-shape-hyperlink`. PPTX import uses it only when one source shape has |
| 62 | both a whole-shape click and descendant run links, because standard SVG cannot |
| 63 | nest their two anchors. Checker/export accept it only on that logical group |
| 64 | with at least one real inline `<a>` descendant, then restore both native click |
| 65 | levels. Every ordinary whole-object link uses the standard outer `<a href>`. |
| 66 | |
| 67 | --- |
| 68 | |
| 69 | ## 3. Native Result and Preservation |
| 70 | |
| 71 | | Carrier / target | Native result | |
| 72 | |---|---| |
| 73 | | Inline external link | `a:rPr/a:hlinkClick` plus an external hyperlink relationship | |
| 74 | | Whole-object external link | `p:cNvPr/a:hlinkClick` on each clickable leaf plus one shared external relationship | |
| 75 | | Inline or whole-object slide jump | The same click carrier plus an internal slide relationship and `ppaction://hlinksldjump` | |
| 76 | | Supported PPTX import | Reconstruct the same canonical SVG `<a href>` form | |
| 77 | |
| 78 | **Hard rule — Fill Native preservation**: Preserve external links. Retarget a |
| 79 | same-deck jump only when its source target maps unambiguously to one output |
| 80 | slide; omitted or duplicated targets fail closed instead of linking to an |
| 81 | orphan or wrong slide. |
| 82 | |
| 83 | **Hard rule — Enhance Native preservation**: Preserve existing hyperlink XML |
| 84 | and relationships unchanged. This route does not use the SVG authoring contract |
| 85 | to add new links. |
| 86 | |
| 87 | --- |
| 88 | |
| 89 | ## 4. Exclusions and Validation |
| 90 | |
| 91 | **Forbidden — unsupported action settings**: Mouse-over links, custom shows, |
| 92 | first/last/next/previous navigation actions, program or macro execution, OLE or |
| 93 | file actions, and arbitrary `ppaction://` or relationship injection are outside |
| 94 | this contract. An `actionButton*` preset remains visual geometry until wrapped |
| 95 | in an ordinary supported hyperlink anchor. |
| 96 | |
| 97 | **Validation**: The final SVG checker validates carrier structure, target |
| 98 | syntax, and slide range. Export validates relationship type/mode and final |
| 99 | presentation-roster membership. Unsupported PPTX click actions produce an |
| 100 | import diagnostic; strict import fails rather than fabricating an SVG link. |
| 101 |