Commit 625afdf7c0
625afdf7c03229accfc3a3a0baae67381ace6504
parent: a4008c4a7f
Verified · cmc
cmc <hello@cleberg.net> · 2026-10-07 23:32 UTC
Tangle :comments noweb with :noweb-ref blocks
A :noweb-ref block without a name is wrapped in the including block's
link with an empty name, as Org writes it. Comments start at the
lines' least indentation, as comment-region puts them.
Layout: unified · split
Sources/OrgCore/Compute/Babel.swift
+6 −2
| @@ -481,12 +481,16 @@ public enum Babel { |
| 481 | 481 | ? try expandNoweb(other, params: otherParams, model: model, text: text, tangling: tangling, depth: depth + 1, links: links) |
| 482 | 482 | : normalizedBody(other) |
| 483 | 483 | guard commenting, let links else { return b } |
| 484 | | guard other.name != nil else { throw Failure.message(":comments noweb with :noweb-ref blocks isn't supported yet; nothing was tangled.") } |
| 485 | 484 | // `c-wrap`: commented in this block's language, trimmed. |
| 486 | 485 | func wrap(_ s: String) throws -> String { |
| 487 | 486 | try Tangle.commentRegion(s, language: block.language ?? "").trimmingCharacters(in: .whitespacesAndNewlines) |
| 488 | 487 | } |
| 489 | | let (begin, end) = try links(other, otherParams) |
| 488 | var (begin, end) = try links(other.name == nil ? block : other, other.name == nil ? params : otherParams) |
| 489 | // A `:noweb-ref` block without a name: the link is the including block's, the name empty. |
| 490 | if other.name == nil { |
| 491 | if let split = begin.range(of: "][") { begin = begin[..<split.lowerBound] + "][]]" } |
| 492 | end = " ends here" |
| 493 | } |
| 490 | 494 | return try wrap(begin) + "\n" + b + "\n" + (try wrap(end)) + "\n" |
| 491 | 495 | } |
| 492 | 496 | func inCommentedHeading(_ b: SrcBlockInfo) -> Bool { |
Sources/OrgCore/Compute/Tangle.swift
+5 −2
| @@ -315,8 +315,11 @@ public enum Tangle { |
| 315 | 315 | guard let syntax = commentSyntax[language] else { |
| 316 | 316 | throw Babel.Failure.message(":comments needs the comment syntax of \(language.isEmpty ? "the block's language" : language), which isn't known yet; nothing was tangled.") |
| 317 | 317 | } |
| 318 | | return text.components(separatedBy: "\n").map { line in |
| 319 | | line.contains(where: { !$0.isWhitespace }) ? syntax.start + line + syntax.end : line |
| 318 | // The comment starts at the lines' least indentation, as `comment-region` puts it. |
| 319 | let lines = text.components(separatedBy: "\n") |
| 320 | let indent = lines.filter { $0.contains(where: { !$0.isWhitespace }) }.map { $0.prefix { $0 == " " || $0 == "\t" }.count }.min() ?? 0 |
| 321 | return lines.map { line in |
| 322 | line.contains(where: { !$0.isWhitespace }) ? String(line.prefix(indent)) + syntax.start + line.dropFirst(indent) + syntax.end : line |
| 320 | 323 | }.joined(separator: "\n") |
| 321 | 324 | } |
| 322 | 325 | |
Tests/OrgCoreTests/TangleTests.swift
+10
| @@ -143,6 +143,16 @@ struct TangleTests { |
| 143 | 143 | #+begin_src conf :tangle out.conf :comments noweb :noweb yes |
| 144 | 144 | a=<<named-py>> |
| 145 | 145 | #+end_src |
| 146 | #+begin_src sh :noweb-ref setup |
| 147 | echo one |
| 148 | #+end_src |
| 149 | #+begin_src sh :noweb-ref setup |
| 150 | echo two |
| 151 | #+end_src |
| 152 | #+begin_src sh :tangle refs.sh :noweb yes :comments noweb |
| 153 | <<setup>> |
| 154 | echo main |
| 155 | #+end_src |
| 146 | 156 | #+begin_src lua :tangle out.lua |
| 147 | 157 | x = 1 |
| 148 | 158 | #+end_src |