Skip to content

Commit

Permalink
Merge branch 'main' into allow-separate-strong-emphasis-marker
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle-Ye authored Jul 13, 2023
2 parents 8f7ca55 + 6b9aade commit b9f1384
Show file tree
Hide file tree
Showing 25 changed files with 1,092 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Swift `Markdown` is a Swift package for parsing, building, editing, and analyzin

The parser is powered by GitHub-flavored Markdown's [cmark-gfm](https://github.com/github/cmark-gfm) implementation, so it follows the spec closely. As the needs of the community change, the effective dialect implemented by this library may change.

The markup tree provided by this package is comprised of immutable/persistent, thread-safe, copy-on-write value types that only copy substructure that has changed. Other examples of the main strategy behind this library can be seen in Swift's [lib/Syntax](https://github.com/apple/swift/tree/master/lib/Syntax) and its Swift bindings, [SwiftSyntax](https://github.com/apple/swift-syntax).
The markup tree provided by this package is comprised of immutable/persistent, thread-safe, copy-on-write value types that only copy substructure that has changed. Other examples of the main strategy behind this library can be seen in [SwiftSyntax](https://github.com/apple/swift-syntax).

## Getting Started Using Markup

Expand Down
2 changes: 2 additions & 0 deletions Snippets/Parsing/test.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Sample document

This is a *sample document*.

<!-- Copyright (c) 2022 Apple Inc and the Swift Project authors. All Rights Reserved. -->
6 changes: 5 additions & 1 deletion Sources/Markdown/Base/Markup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func makeMarkup(_ data: _MarkupData) -> Markup {
return SymbolLink(data)
case .inlineAttributes:
return InlineAttributes(data)
case .doxygenParam:
return DoxygenParameter(data)
case .doxygenReturns:
return DoxygenReturns(data)
}
}

Expand Down Expand Up @@ -261,7 +265,7 @@ extension Markup {
public func child(through path: TypedChildIndexPath) -> Markup? {
var element: Markup = self
for pathElement in path {
guard pathElement.index <= raw.markup.childCount else {
guard pathElement.index <= element.childCount else {
return nil
}

Expand Down
11 changes: 11 additions & 0 deletions Sources/Markdown/Base/RawMarkup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ enum RawMarkupData: Equatable {
case tableBody
case tableRow
case tableCell(colspan: UInt, rowspan: UInt)

case doxygenParam(name: String)
case doxygenReturns
}

extension RawMarkupData {
Expand Down Expand Up @@ -330,6 +333,14 @@ final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> {
static func tableCell(parsedRange: SourceRange?, colspan: UInt, rowspan: UInt, _ children: [RawMarkup]) -> RawMarkup {
return .create(data: .tableCell(colspan: colspan, rowspan: rowspan), parsedRange: parsedRange, children: children)
}

static func doxygenParam(name: String, parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup {
return .create(data: .doxygenParam(name: name), parsedRange: parsedRange, children: children)
}

static func doxygenReturns(parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup {
return .create(data: .doxygenReturns, parsedRange: parsedRange, children: children)
}
}

fileprivate extension Sequence where Element == RawMarkup {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
This source file is part of the Swift.org open source project
Copyright (c) 2023 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
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
/// `\param name description`, where `description` extends until the next blank line or the next
/// parsed command. For example, the following input will return two `DoxygenParam` instances:
///
/// ```markdown
/// \param coordinate The coordinate used to center the transformation.
/// \param matrix The transformation matrix that describes the transformation.
/// For more information about transformation matrices, refer to the Transformation
/// documentation.
/// ```
public struct DoxygenParameter: BlockContainer {
public var _data: _MarkupData

init(_ raw: RawMarkup) throws {
guard case .doxygenParam = raw.data else {
throw RawMarkup.Error.concreteConversionError(from: raw, to: DoxygenParameter.self)
}
let absoluteRaw = AbsoluteRawMarkup(markup: raw, metadata: MarkupMetadata(id: .newRoot(), indexInParent: 0))
self.init(_MarkupData(absoluteRaw))
}

init(_ data: _MarkupData) {
self._data = data
}

public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenParameter(self)
}
}

public extension DoxygenParameter {
/// Create a new Doxygen parameter definition.
///
/// - Parameter name: The name of the parameter being described.
/// - Parameter children: Block child elements.
init<Children: Sequence>(name: String, children: Children) where Children.Element == BlockMarkup {
try! self.init(.doxygenParam(name: name, parsedRange: nil, children.map({ $0.raw.markup })))
}

/// Create a new Doxygen parameter definition.
///
/// - Parameter name: The name of the parameter being described.
/// - Parameter children: Block child elements.
init(name: String, children: BlockMarkup...) {
self.init(name: name, children: children)
}

/// The name of the parameter being described.
var name: String {
get {
guard case let .doxygenParam(name) = _data.raw.markup.data else {
fatalError("\(self) markup wrapped unexpected \(_data.raw)")
}
return name
}
set {
_data = _data.replacingSelf(.doxygenParam(
name: newValue,
parsedRange: nil,
_data.raw.markup.copyChildren()
))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
This source file is part of the Swift.org open source project
Copyright (c) 2023 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
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
/// `\returns description`, where `description` continues until the next blank line or parsed
/// command. The commands `\return` and `\result` are also accepted, with the same format.
///
/// ```markdown
/// \returns A freshly-created object.
/// ```
public struct DoxygenReturns: BlockContainer {
public var _data: _MarkupData

init(_ raw: RawMarkup) throws {
guard case .doxygenReturns = raw.data else {
throw RawMarkup.Error.concreteConversionError(from: raw, to: DoxygenReturns.self)
}
let absoluteRaw = AbsoluteRawMarkup(markup: raw, metadata: MarkupMetadata(id: .newRoot(), indexInParent: 0))
self.init(_MarkupData(absoluteRaw))
}

init(_ data: _MarkupData) {
self._data = data
}

public func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
return visitor.visitDoxygenReturns(self)
}
}

public extension DoxygenReturns {
/// Create a new Doxygen parameter definition.
///
/// - Parameter name: The name of the parameter being described.
/// - Parameter children: Block child elements.
init<Children: Sequence>(children: Children) where Children.Element == BlockMarkup {
try! self.init(.doxygenReturns(parsedRange: nil, children.map({ $0.raw.markup })))
}

/// Create a new Doxygen parameter definition.
///
/// - Parameter name: The name of the parameter being described.
/// - Parameter children: Block child elements.
init(children: BlockMarkup...) {
self.init(children: children)
}
}
12 changes: 11 additions & 1 deletion Sources/Markdown/Inline Nodes/Inline Containers/Link.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift.org open source project
Copyright (c) 2021 Apple Inc. and the Swift project authors
Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
Expand Down Expand Up @@ -63,6 +63,16 @@ public extension Link {
}
}

var isAutolink: Bool {
guard let destination = destination,
childCount == 1,
let text = child(at: 0) as? Text,
destination == text.string else {
return false
}
return true
}

// MARK: Visitation

func accept<V: MarkupVisitor>(_ visitor: inout V) -> V.Result {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Markdown/Markdown.docc/Markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Swift `Markdown` is a Swift package for parsing, building, editing, and analyzin

The parser is powered by GitHub-flavored Markdown's [cmark-gfm](https://github.com/github/cmark-gfm) implementation, so it follows the spec closely. As the needs of the community change, the effective dialect implemented by this library may change.

The markup tree provided by this package is comprised of immutable/persistent, thread-safe, copy-on-write value types that only copy substructure that has changed. Other examples of the main strategy behind this library can be seen in Swift's [lib/Syntax](https://github.com/apple/swift/tree/master/lib/Syntax) and its Swift bindings, [SwiftSyntax](https://github.com/apple/swift-syntax).
The markup tree provided by this package is comprised of immutable/persistent, thread-safe, copy-on-write value types that only copy substructure that has changed. Other examples of the main strategy behind this library can be seen in [SwiftSyntax](https://github.com/apple/swift-syntax).

## Topics

Expand Down
1 change: 1 addition & 0 deletions Sources/Markdown/Markdown.docc/Markdown/BlockMarkup.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@

## See Also
- <doc:BlockDirectives>
- <doc:DoxygenCommands>

<!-- Copyright (c) 2021-2022 Apple Inc and the Swift Project authors. All Rights Reserved. -->
50 changes: 50 additions & 0 deletions Sources/Markdown/Markdown.docc/Markdown/DoxygenCommands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Doxygen Commands

Include a limited set of Doxygen commands in parsed Markdown.

Swift Markdown includes an option to parse a limited set of Doxygen commands, to facilitate
transitioning from a different Markdown parser. To include these commands in the output, include
the options ``ParseOptions/parseBlockDirectives`` and ``ParseOptions/parseMinimalDoxygen`` when
parsing a ``Document``. In the resulting document, parsed Doxygen commands appear as regular
``Markup`` types in the hierarchy.

## Parsing Strategy

Doxygen commands are written by using either a backslash (`\`) or an at-sign (`@`) character,
followed by the name of the command. Any parameters are then parsed as whitespace-separated words,
then a "description" argument is taken from the remainder of the line, as well as all lines
immediately after the command, until the parser sees a blank line, another Doxygen command, or a
block directive. The description is then parsed for regular Markdown formatting, which is then
stored as the children of the command type. For example, with Doxygen parsing turned on, the
following document will parse three separate commands and one block directive:

```markdown
\param thing The thing.
This is the thing that is modified.
\param otherThing The other thing.

\returns A thing that has been modified.
@Comment {
This is not part of the `\returns` command.
}
```

Trailing lines in a command's description are allowed to be indented relative to the command. For
example, the description below is parsed as a paragraph, not a code block:

```markdown
\param thing
The thing.
This is the thing that is modified.
```

Doxygen commands are not parsed within code blocks or block directive content.

## Topics

### Commands

- ``DoxygenParam``
- ``DoxygenReturns``

<!-- Copyright (c) 2023 Apple Inc and the Swift Project authors. All Rights Reserved. -->
2 changes: 2 additions & 0 deletions Sources/Markdown/Markdown.docc/Snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ a Markdown document to a consistent, preferred style.
@Snippet(path: "swift-markdown/Snippets/Formatting/PreferredHeadingStyle")
@Snippet(path: "swift-markdown/Snippets/Formatting/ThematicBreakCharacter")
@Snippet(path: "swift-markdown/Snippets/Formatting/UseCodeFence")

<!-- Copyright (c) 2022 Apple Inc and the Swift Project authors. All Rights Reserved. -->
Loading

0 comments on commit b9f1384

Please sign in to comment.