MCPcopy Create free account
hub / github.com/cli/cli / attachAssetsToMarkdown

Function attachAssetsToMarkdown

internal/attachments/references.go:93–182  ·  view source on GitHub ↗

attachAssetsToMarkdown points every markdown reference to an attached file at that file's asset URL, and reports which arguments the markdown never referenced. ![alt](./file) alone in a paragraph image: swap the path video: the bare URL, which plays ![alt](./file) anywhere else image

(v attachableMarkdown)

Source from the content-addressed store, hash-verified

91//
92// A path inside a code fence or an inline code span is left alone.
93func attachAssetsToMarkdown(v attachableMarkdown) (attachedMarkdown, error) {
94 md := v.markdown
95 if len(v.args) == 0 {
96 return attachedMarkdown{Rewritten: md}, nil
97 }
98
99 src, refs, attachmentArgs := []byte(md), v.refs, v.args
100
101 var edits []edit
102
103 // Looping over the markdown references to produce a plan for edits.
104 for _, r := range refs {
105 arg := attachmentArgs[r.attachmentArg]
106
107 // It's not been uploaded.
108 if arg.URL == "" {
109 continue
110 }
111
112 // Reference style links get rewritten at their definitions, not inline.
113 if r.referenceStyle() {
114 for _, def := range r.defs {
115 dest, ok := linkReferenceDestination(src, def)
116 // TODO: We skip the edit because a definition split across a blockquote
117 // carries the ">" marker, and rewriting it would mangle the quote. The
118 // fallback that appends unrewritten files operates per file. A rewritable
119 // reference to the same file elsewhere suppresses the append fallback,
120 // leaving this definition pointing at its original local path. We accept
121 // this because the tool leaves the reference exactly as the author wrote
122 // it, rewriting only what can be safely rewritten.
123 if !ok {
124 continue
125 }
126 edits = append(edits, edit{r.attachmentArg, dest, arg.URL})
127 }
128 continue
129 }
130
131 at := r.ranges
132 playerEmbed := arg.RendersAsPlayer && r.isEmbed
133
134 switch {
135 case !playerEmbed:
136 // Only the destination moves, so alt text, titles, and formatting
137 // inside the label survive.
138 edits = append(edits, edit{r.attachmentArg, at.dest, arg.URL})
139
140 case standsAlone(src, r.block, at.node):
141 // A player only renders from a bare URL alone in a paragraph, so
142 // the whole node goes and any alt text is dropped.
143 edits = append(edits, edit{r.attachmentArg, at.node, arg.URL})
144
145 default:
146 // Degrade to a link: only the "!" and the destination move, so a
147 // reference nested in the alt text is still rewritten in place.
148 //
149 // A literal "!" before the embed's own would pair with the "["
150 // left behind and re-form an embed, so it is absorbed into the

Callers 3

UploadAndAttachMethod · 0.85

Calls 6

linkReferenceDestinationFunction · 0.85
standsAloneFunction · 0.85
isEscapedFunction · 0.85
escapeAltFunction · 0.85
applyEditsFunction · 0.85
referenceStyleMethod · 0.80

Tested by 2