diff --git a/Sources/Markdown/Walker/Walkers/MarkupFormatter.swift b/Sources/Markdown/Walker/Walkers/MarkupFormatter.swift index 310280a5..6b472018 100644 --- a/Sources/Markdown/Walker/Walkers/MarkupFormatter.swift +++ b/Sources/Markdown/Walker/Walkers/MarkupFormatter.swift @@ -248,6 +248,7 @@ public struct MarkupFormatter: MarkupWalker { var thematicBreakCharacter: ThematicBreakCharacter var thematicBreakLength: UInt var emphasisMarker: EmphasisMarker + var strongEmphasisMarker: EmphasisMarker var condenseAutolinks: Bool var preferredHeadingStyle: PreferredHeadingStyle var preferredLineLimit: PreferredLineLimit? @@ -264,7 +265,8 @@ public struct MarkupFormatter: MarkupWalker { - defaultCodeBlockLanguage: The default language string to use when code blocks don't have a language and will be printed as fenced code blocks. - thematicBreakCharacter: The character to use for thematic breaks. - thematicBreakLength: The length of printed thematic breaks. - - emphasisMarker: The character to use for emphasis and strong emphasis markers. + - emphasisMarker: The character to use for emphasis markers. + - strongEmphasisMarker: The character to use for strong emphasis markers. If no value is provided, uses `emphasisMarker`. - condenseAutolinks: Print links whose link text and destination match as autolinks, e.g. ``. - preferredHeadingStyle: The preferred heading style. - lineLimit: The preferred maximum line length and method for splitting ``Text`` elements in an attempt to maintain that line length. @@ -277,6 +279,7 @@ public struct MarkupFormatter: MarkupWalker { thematicBreakCharacter: ThematicBreakCharacter = .dash, thematicBreakLength: UInt = 5, emphasisMarker: EmphasisMarker = .star, + strongEmphasisMarker: EmphasisMarker? = nil, condenseAutolinks: Bool = true, preferredHeadingStyle: PreferredHeadingStyle = .atx, preferredLineLimit: PreferredLineLimit? = nil, @@ -288,6 +291,7 @@ public struct MarkupFormatter: MarkupWalker { self.defaultCodeBlockLanguage = defaultCodeBlockLanguage self.thematicBreakCharacter = thematicBreakCharacter self.emphasisMarker = emphasisMarker + self.strongEmphasisMarker = strongEmphasisMarker ?? emphasisMarker self.condenseAutolinks = condenseAutolinks self.preferredHeadingStyle = preferredHeadingStyle self.preferredLineLimit = preferredLineLimit @@ -862,9 +866,9 @@ public struct MarkupFormatter: MarkupWalker { } public mutating func visitStrong(_ strong: Strong) { - print(String(repeating: formattingOptions.emphasisMarker.rawValue, count: 2), for: strong) + print(String(repeating: formattingOptions.strongEmphasisMarker.rawValue, count: 2), for: strong) descendInto(strong) - print(String(repeating: formattingOptions.emphasisMarker.rawValue, count: 2), for: strong) + print(String(repeating: formattingOptions.strongEmphasisMarker.rawValue, count: 2), for: strong) } public mutating func visitText(_ text: Text) { diff --git a/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift b/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift index 37750e62..972398c5 100644 --- a/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift +++ b/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift @@ -542,7 +542,40 @@ class MarkupFormatterOptionsTests: XCTestCase { let printed = document.format(options: .init(emphasisMarker: .underline)) XCTAssertEqual(underline, printed) } + } + + do { + let underline = "__strong__" + let star = "**strong**" + do { + let document = Document(parsing: underline) + let printed = document.format(options: .init(strongEmphasisMarker: .star)) + XCTAssertEqual(star, printed) + } + + do { + let document = Document(parsing: star) + let printed = document.format(options: .init(strongEmphasisMarker: .underline)) + XCTAssertEqual(underline, printed) + } + } + + do { + let underline = "__strong__" + let star = "**strong**" + + do { + let document = Document(parsing: underline) + let printed = document.format(options: .init(emphasisMarker: .underline, strongEmphasisMarker: .star)) + XCTAssertEqual(star, printed) + } + + do { + let document = Document(parsing: star) + let printed = document.format(options: .init(emphasisMarker: .star, strongEmphasisMarker: .underline)) + XCTAssertEqual(underline, printed) + } } } diff --git a/Tools/markdown-tool/Commands/FormatCommand.swift b/Tools/markdown-tool/Commands/FormatCommand.swift index 4f81c791..e9817eab 100644 --- a/Tools/markdown-tool/Commands/FormatCommand.swift +++ b/Tools/markdown-tool/Commands/FormatCommand.swift @@ -96,6 +96,9 @@ extension MarkdownCommand { @Option(help: "Emphasis marker; choices: \(MarkupFormatter.Options.EmphasisMarker.allCases.map { $0.rawValue }.joined(separator: ", "))") var emphasisMarker: String = "*" + @Option(help: "Strong emphasis marker; choices: \(MarkupFormatter.Options.EmphasisMarker.allCases.map { $0.rawValue }.joined(separator: ", "))") + var strongEmphasisMarker: String? + @Flag(inversion: .prefixedNo, exclusivity: .chooseLast, help: "Condense links whose text matches their destination to 'autolinks' e.g. ") var condenseAutolinks: Bool = true @@ -206,6 +209,16 @@ extension MarkdownCommand { throw ArgumentParser.ValidationError("The value '\(self.emphasisMarker)' is invalid for '--emphasis-marker'") } + let strongEmphasisMarker: MarkupFormatter.Options.EmphasisMarker? + if let marker = self.strongEmphasisMarker { + guard let marker = MarkupFormatter.Options.EmphasisMarker(argument: marker) else { + throw ArgumentParser.ValidationError("The value '\(marker)' is invalid for '--strong-emphasis-marker'") + } + strongEmphasisMarker = marker + } else { + strongEmphasisMarker = nil + } + guard let unorderedListMarker = MarkupFormatter.Options.UnorderedListMarker(argument: unorderedListMarker) else { throw ArgumentParser.ValidationError("The value '\(self.unorderedListMarker)' is invalid for '--unordered-list-marker'") } @@ -229,6 +242,7 @@ extension MarkdownCommand { thematicBreakCharacter: thematicBreakCharacter, thematicBreakLength: thematicBreakLength, emphasisMarker: emphasisMarker, + strongEmphasisMarker: strongEmphasisMarker, condenseAutolinks: condenseAutolinks, preferredHeadingStyle: preferredHeadingStyle, preferredLineLimit: preferredLineLimit,