Skip to content

Commit

Permalink
Support converting Markdown into a string without any markup.
Browse files Browse the repository at this point in the history
  • Loading branch information
objecthub committed Aug 4, 2024
1 parent 8f17ab3 commit d9bc97f
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.1.9 (2024-08-04)

- Support converting Markdown into a string without any markup

## 1.1.8 (2024-05-01)
- Fix `Color.hexString` on iOS to handle black correctly
- Clean up `Package.swift`
Expand Down
40 changes: 40 additions & 0 deletions Sources/MarkdownKit/Block.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,42 @@ public enum Block: Equatable, CustomStringConvertible, CustomDebugStringConverti
return self.description
}
}

/// Returns raw text for this block, i.e. ignoring all markup.
public var string: String {
switch self {
case .document(let blocks):
return blocks.string
case .blockquote(let blocks):
return blocks.string
case .list(_, _, let blocks):
return blocks.string
case .listItem(_, _, let blocks):
return blocks.string
case .paragraph(let text):
return text.string
case .heading(_, let text):
return text.string
case .indentedCode(let lines):
return lines.map { String($0) }.joined()
case .fencedCode(_, let lines):
return lines.map { String($0) }.joined(separator: "\n")
case .htmlBlock(_):
return ""
case .referenceDef(_, _, let lines):
return lines.map { String($0) }.joined(separator: " ")
case .thematicBreak:
return "\n\n"
case .table(let headers, _, let rows):
return headers.map { $0.string }.joined(separator: " | ") + "\n" +
rows.map { $0.map { $0.string }.joined(separator: " | ") }
.joined(separator: "\n")
case .definitionList(let defs):
return defs.map { $0.string }.joined(separator: "\n\n")
case .custom(let obj):
return obj.string
}
}

fileprivate static func string(from blocks: Blocks) -> String {
var res = ""
Expand Down Expand Up @@ -295,6 +331,10 @@ public struct Definition: Equatable, CustomStringConvertible, CustomDebugStringC
public var debugDescription: String {
return self.description
}

public var string: String {
return "\(self.item.rawDescription): \(self.descriptions.string)"
}
}

public typealias Definitions = ContiguousArray<Definition>
5 changes: 5 additions & 0 deletions Sources/MarkdownKit/Blocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ extension Blocks {
public var isSingleton: Bool {
return self.count == 1
}

/// Returns raw text for this sequence of blocks.
public var string: String {
return self.map { $0.string }.joined(separator: "\n")
}
}
8 changes: 8 additions & 0 deletions Sources/MarkdownKit/CustomBlock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Foundation
/// externally (i.e. not by the MarkdownKit framework).
///
public protocol CustomBlock: CustomStringConvertible, CustomDebugStringConvertible {
var string: String { get }
func equals(to other: CustomBlock) -> Bool
func parse(via parser: InlineParser) -> Block
func generateHtml(via htmlGen: HtmlGenerator, tight: Bool) -> String
Expand All @@ -34,3 +35,10 @@ public protocol CustomBlock: CustomStringConvertible, CustomDebugStringConvertib
tight: Bool) -> String
#endif
}

extension CustomBlock {
/// By default, the custom block does not have any raw string content.
public var string: String {
return ""
}
}
14 changes: 8 additions & 6 deletions Sources/MarkdownKit/Text.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ public struct Text: Collection, Equatable, CustomStringConvertible, CustomDebugS
/// Returns a raw description of this `Text` object as a string, i.e. as if the text
/// would be represented in Markdown but ignoring all markup.
public var rawDescription: String {
var res = ""
for fragment in self.fragments {
res = res + fragment.rawDescription
}
return res
return self.fragments.map { $0.rawDescription }.joined()
}


/// Returns a raw description of this `Text` object as a string for which all markup
/// gets ignored.
public var string: String {
return self.fragments.map { $0.string }.joined()
}

/// Returns a debug description of this `Text` object.
public var debugDescription: String {
var res = ""
Expand Down
19 changes: 18 additions & 1 deletion Sources/MarkdownKit/TextFragment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,24 @@ public enum TextFragment: Equatable, CustomStringConvertible, CustomDebugStringC
return customTextFragment.rawDescription
}
}


/// Returns a raw description of this `TextFragment` object as a string in which all
/// markup gets ignored.
public var string: String {
switch self {
case .html(_):
return ""
case .delimiter(let ch, let n, _):
var res = String(ch)
for _ in 1..<n {
res.append(ch)
}
return res
default:
return self.rawDescription
}
}

/// Returns a debug description of this `TextFragment` object.
public var debugDescription: String {
switch self {
Expand Down
8 changes: 8 additions & 0 deletions Tests/MarkdownKitTests/MarkdownBlockTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@ class MarkdownBlockTests: XCTestCase, MarkdownKitFactory {
"</code></pre>\n"),
paragraph("okay")))
}

func testToString() {
XCTAssertEqual(parseBlocks(" # First\n ## Second \n### Third").string, "First\nSecond\nThird")
XCTAssertEqual(parseBlocks("> # Hello\n> Next line\n And last line").string, "Hello\nNext line And last line")
XCTAssertEqual(parseBlocks("one\n\n foo\n bar\n\ntwo").string, "one\n foo\nbar\n\ntwo")
XCTAssertEqual(parseBlocks("- foo\n - bar\n - baz\n - boo").string, "foo\nbar\nbaz\nboo")
XCTAssertEqual(parseBlocks("- foo\n - one\n - two\n \n three").string, "foo\none\ntwo\nthree")
}

func testDebug() {

Expand Down

0 comments on commit d9bc97f

Please sign in to comment.