diff options
| author | Christian Cleberg <[email protected]> | 2026-07-20 14:48:00 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-20 14:48:54 -0500 |
| commit | 1c3d19b233f135a059f5d111dd1a7514af25ed3f (patch) | |
| tree | 718d4ed069e376d153d8b26cfb690af5063c4606 /DomainReportExporter.swift | |
| parent | 91041af60b5a98ef01f5588478302c1ef04e043d (diff) | |
| download | domain-dig-1c3d19b233f135a059f5d111dd1a7514af25ed3f.tar.gz domain-dig-1c3d19b233f135a059f5d111dd1a7514af25ed3f.tar.bz2 domain-dig-1c3d19b233f135a059f5d111dd1a7514af25ed3f.zip | |
fix: markdown report underlines and duplicate DNS record values
The plain-text-to-Markdown transform only recognized '-' underlines, but
batchText writes '=' — under the document title and as a 48-character
separator between reports. Both leaked through as literal bullets, so a
generated report opened with:
# Scheduled Watchlist Report
- ==========================
Title underlines are now consumed alongside the title, '=' underlines
promote to H2 the same as '-', and standalone divider runs render as a
Markdown horizontal rule.
Separately, the DNS section concatenated apex and wildcard records
without dedup. On a domain with wildcard DNS resolving to the same
addresses as the apex, every value was listed twice. Now deduped while
preserving order, so a wildcard value that genuinely differs is still
shown.
Diffstat (limited to 'DomainReportExporter.swift')
| -rw-r--r-- | DomainReportExporter.swift | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/DomainReportExporter.swift b/DomainReportExporter.swift index 7199d03..a8e2ee9 100644 --- a/DomainReportExporter.swift +++ b/DomainReportExporter.swift @@ -77,14 +77,23 @@ enum DomainReportExporter { let line = lines[index] if index == 0, line == title { index += 1 + if index < lines.count, isUnderline(lines[index], for: line) { + index += 1 + } continue } - if index + 1 < lines.count, !line.isEmpty, lines[index + 1] == String(repeating: "-", count: line.count) { + if index + 1 < lines.count, !line.isEmpty, isUnderline(lines[index + 1], for: line) { output.append("") output.append("## \(line)") index += 2 continue } + if isRule(line) { + output.append("") + output.append("---") + index += 1 + continue + } if line.isEmpty || line.hasPrefix("-") || line.hasPrefix(" ") { output.append(line) } else { @@ -95,6 +104,21 @@ enum DomainReportExporter { return output.joined(separator: "\n") } + /// True when `line` is a run of `-` or `=` exactly as long as the heading it + /// underlines. `batchText` uses `=` for the document title, `appendSection` + /// uses `-` for section headers. + private static func isUnderline(_ line: String, for heading: String) -> Bool { + guard !heading.isEmpty else { return false } + return line == String(repeating: "-", count: heading.count) + || line == String(repeating: "=", count: heading.count) + } + + /// True for a standalone divider not attached to a heading — `batchText` + /// emits a fixed 48-character `=` run between reports. + private static func isRule(_ line: String) -> Bool { + line.count >= 3 && (line.allSatisfy { $0 == "=" } || line.allSatisfy { $0 == "-" }) + } + /// Renders Markdown as a simple monospaced multi-page PDF. Foundation-only /// consumers (no UIKit available) get the Markdown bytes back instead. static func pdfData(fromMarkdown markdown: String) -> Data { @@ -249,7 +273,10 @@ enum DomainReportExporter { } else { dnsLines.append("Records:") for section in report.dns.recordSections { - let values = (section.records + section.wildcardRecords).map(\.value) + var seen: Set<String> = [] + let values = (section.records + section.wildcardRecords) + .map(\.value) + .filter { seen.insert($0).inserted } let renderedValues = values.isEmpty ? "None" : values.joined(separator: " | ") dnsLines.append(" \(section.recordType.rawValue): \(renderedValues)") } |
