Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let cmarkPackageName = ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DE

let package = Package(
name: "swift-markdown",
platforms: [.macOS(.v10_15)],
products: [
.library(
name: "Markdown",
Expand Down
8 changes: 7 additions & 1 deletion Sources/Markdown/Base/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if canImport(Foundation)
import Foundation
#endif

/// A markup element representing the top level of a whole document.
///
Expand Down Expand Up @@ -41,7 +43,7 @@ public extension Document {
/// - parameter options: options for parsing Markdown text.
/// - parameter source: an explicit source URL from which the input `string` came for marking source locations.
/// This need not be a file URL.
init(parsing string: String, source: URL? = nil, options: ParseOptions = []) {
init(parsing string: String, source: SourceIdentifier? = nil, options: ParseOptions = []) {
if options.contains(.parseBlockDirectives) {
self = BlockDirectiveParser.parse(string, source: source,
options: options)
Expand All @@ -50,6 +52,7 @@ public extension Document {
}
}

#if canImport(Foundation)
/// Parse a file's contents into a `Document`.
///
/// - parameter file: a file URL from which to load Markdown text to parse.
Expand All @@ -63,6 +66,7 @@ public extension Document {
self = MarkupParser.parseString(string, source: file, options: options)
}
}
#endif

/// Create a document from a sequence of block markup elements.
init(_ children: some Sequence<BlockMarkup>) {
Expand All @@ -77,7 +81,9 @@ public extension Document {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDocument(self)
}
#endif
}
6 changes: 4 additions & 2 deletions Sources/Markdown/Base/Markup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ func makeMarkup(_ data: _MarkupData) -> Markup {
/// > Note: All supported markup elements are already implemented in the framework.
/// Use this protocol only as a generic constraint.
public protocol Markup {
#if !hasFeature(Embedded)
/// Accept a `MarkupVisitor` and call the specific visitation method for this element.
///
/// - parameter visitor: The `MarkupVisitor` visiting the element.
/// - returns: The result of the visit.
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result
#endif

/// The data backing the markup element.
/// > Note: This property is an implementation detail; do not use it directly.
Expand Down Expand Up @@ -122,7 +124,7 @@ extension Markup {
///
/// - Complexity: `O(1)`
var subtreeCount: Int {
return raw.markup.header.subtreeCount
return raw.markup.subtreeCount
}

/// Return this element without ``SoftBreak`` elements, or `nil` if this
Expand Down Expand Up @@ -178,7 +180,7 @@ extension Markup {
///
/// - Complexity: `O(1)`
public var childCount: Int {
return raw.markup.header.childCount
return raw.markup.childCount
}

/// `true` if this element has no children.
Expand Down
79 changes: 67 additions & 12 deletions Sources/Markdown/Base/RawMarkup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

#if canImport(Foundation)
import Foundation
#endif

/// The data specific to a kind of markup element.
///
Expand Down Expand Up @@ -93,6 +95,54 @@ public struct RawMarkupHeader {
var parsedRange: SourceRange?
}

#if hasFeature(Embedded)
/// Embedded Swift variant: uses a plain array for children storage instead of
/// tail-allocated ManagedBuffer elements, avoiding the self-referential generic
/// `ManagedBuffer<RawMarkupHeader, RawMarkup>` that causes the compiler's
/// generic specializer to hang (https://github.com/swiftlang/swift/pull/88296).
final class RawMarkup {
var header: RawMarkupHeader
private let _children: [RawMarkup]

fileprivate static func create(data: RawMarkupData, parsedRange: SourceRange?, children: [RawMarkup]) -> RawMarkup {
return RawMarkup(
header: RawMarkupHeader(data: data,
childCount: children.count,
subtreeCount: 1 + children.subtreeCount,
parsedRange: parsedRange),
children: children)
}

private init(header: RawMarkupHeader, children: [RawMarkup]) {
self.header = header
self._children = children
}

var data: RawMarkupData { header.data }
var childCount: Int { header.childCount }
var subtreeCount: Int { header.subtreeCount }
var parsedRange: SourceRange? { header.parsedRange }

func child(at index: Int) -> RawMarkup {
precondition(index < header.childCount)
return _children[index]
}

func copyChildren() -> [RawMarkup] { _children }

var children: some Sequence<RawMarkup> { _children }

enum Error: Swift.Error, CustomStringConvertible {
case concreteConversionError(from: RawMarkup, to: Markup.Type)
var description: String {
switch self {
case let .concreteConversionError(raw, to: type):
return "Can't wrap a \(raw.data) in a \(type)"
}
}
}
}
#else
final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
enum Error: LocalizedError {
case concreteConversionError(from: RawMarkup, to: Markup.Type)
Expand All @@ -103,7 +153,8 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
}
}
}
private static func create(data: RawMarkupData, parsedRange: SourceRange?, children: [RawMarkup]) -> RawMarkup {

fileprivate static func create(data: RawMarkupData, parsedRange: SourceRange?, children: [RawMarkup]) -> RawMarkup {
let buffer = self.create(minimumCapacity: children.count) { _ in
RawMarkupHeader(data: data,
childCount: children.count,
Expand Down Expand Up @@ -155,17 +206,21 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
}

/// The children of this element.
var children: AnySequence<RawMarkup> {
return AnySequence((0..<childCount).lazy.map { Int -> RawMarkup in
self.child(at: 0)
})
var children: some Sequence<RawMarkup> {
return (0..<childCount).lazy.map { _ in self.child(at: 0) }
}

deinit {
return self.withUnsafeMutablePointerToElements {
$0.deinitialize(count: header.childCount)
}
}
}
#endif

// MARK: - Shared API

extension RawMarkup {

// MARK: Aspects

Expand All @@ -174,11 +229,11 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
if self === other {
return true
}
guard self.header.childCount == other.header.childCount,
self.header.data == other.header.data else {
guard self.childCount == other.childCount,
self.data == other.data else {
return false
}
for i in 0..<header.childCount {
for i in 0..<childCount {
guard self.child(at: i).hasSameStructure(as: other.child(at: i)) else {
return false
}
Expand All @@ -197,16 +252,16 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {

let parsedRange: SourceRange?
if preserveRange {
parsedRange = header.parsedRange
parsedRange = self.parsedRange
} else {
parsedRange = newChild.header.parsedRange
parsedRange = newChild.parsedRange
}

return RawMarkup.create(data: header.data, parsedRange: parsedRange, children: newChildren)
return RawMarkup.create(data: data, parsedRange: parsedRange, children: newChildren)
}

func withChildren<Children: Collection>(_ newChildren: Children) -> RawMarkup where Children.Element == RawMarkup {
return .create(data: header.data, parsedRange: header.parsedRange, children: Array(newChildren))
return .create(data: data, parsedRange: parsedRange, children: Array(newChildren))
}

// MARK: Block Creation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ public extension BlockDirective {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitBlockDirective(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public extension BlockQuote {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitBlockQuote(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public extension CustomBlock {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitCustomBlock(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// A parsed Doxygen `\abstract` command.
///
/// The Doxygen support in Swift-Markdown parses `\abstract` commands of the form
Expand All @@ -34,9 +32,11 @@ public struct DoxygenAbstract: BlockContainer {
self._data = data
}

#if !hasFeature(Embedded)
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenAbstract(self)
}
#endif
}

public extension DoxygenAbstract {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// A parsed Doxygen `\discussion` command.
///
/// The Doxygen support in Swift-Markdown parses `\discussion` commands of the form
Expand All @@ -34,9 +32,11 @@ public struct DoxygenDiscussion: BlockContainer {
self._data = data
}

#if !hasFeature(Embedded)
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenDiscussion(self)
}
#endif
}

public extension DoxygenDiscussion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// A parsed Doxygen `\note` command.
///
/// The Doxygen support in Swift-Markdown parses `\note` commands of the form
Expand All @@ -34,9 +32,11 @@ public struct DoxygenNote: BlockContainer {
self._data = data
}

#if !hasFeature(Embedded)
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenNote(self)
}
#endif
}

public extension DoxygenNote {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// A parsed Doxygen `\param` command.
///
/// The Doxygen support in Swift-Markdown parses `\param` commands of the form
Expand Down Expand Up @@ -37,9 +35,11 @@ public struct DoxygenParameter: BlockContainer {
self._data = data
}

#if !hasFeature(Embedded)
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenParameter(self)
}
#endif
}

public extension DoxygenParameter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// A parsed Doxygen `\returns`, `\return`, or `\result` command.
///
/// The Doxygen support in Swift-Markdown parses `\returns` commands of the form
Expand All @@ -34,9 +32,11 @@ public struct DoxygenReturns: BlockContainer {
self._data = data
}

#if !hasFeature(Embedded)
public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenReturns(self)
}
#endif
}

public extension DoxygenReturns {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public extension ListItem {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitListItem(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public extension OrderedList {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitOrderedList(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public extension UnorderedList {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitUnorderedList(self)
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public extension Paragraph {

// MARK: Visitation

#if !hasFeature(Embedded)
func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitParagraph(self)
}
#endif
}
Loading