This commit is contained in:
26
Examples/README.md
Normal file
26
Examples/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# swift-cli-doc
|
||||||
|
|
||||||
|
A tool for building rich documentation for command line applications using result builders and
|
||||||
|
syntax similar to `SwiftUI`.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Add this as a package dependency to your command line application.
|
||||||
|
|
||||||
|
```swift
|
||||||
|
let package = Package(
|
||||||
|
name: "my-tool"
|
||||||
|
...
|
||||||
|
dependencies: [
|
||||||
|
.package(url: "https://git.housh.dev/michael/swift-cli-doc", from: "0.1.0")
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.executableTarget(
|
||||||
|
name: "my-tool",
|
||||||
|
dependencies: [
|
||||||
|
.product(name: "CliDoc", package: "swift-cli-doc")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
```
|
||||||
@@ -9,7 +9,8 @@ struct Application: ParsableCommand {
|
|||||||
subcommands: [
|
subcommands: [
|
||||||
SectionCommand.self,
|
SectionCommand.self,
|
||||||
VStackCommand.self,
|
VStackCommand.self,
|
||||||
HStackCommand.self
|
HStackCommand.self,
|
||||||
|
GroupCommand.self
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
21
Examples/Sources/CliDoc-Examples/GroupCommand.swift
Normal file
21
Examples/Sources/CliDoc-Examples/GroupCommand.swift
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import ArgumentParser
|
||||||
|
import CliDocCore
|
||||||
|
|
||||||
|
struct GroupCommand: ParsableCommand {
|
||||||
|
|
||||||
|
static let configuration = CommandConfiguration(commandName: "group")
|
||||||
|
|
||||||
|
func run() throws {
|
||||||
|
let group = Group {
|
||||||
|
"My headline."
|
||||||
|
"\n"
|
||||||
|
"Some content".color(.green)
|
||||||
|
"\n"
|
||||||
|
"Foo Bar".italic()
|
||||||
|
}
|
||||||
|
.color(.blue)
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("\(group.render())")
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Sources/CliDocCore/Documentation.docc/Resources/group.png
LFS
Normal file
BIN
Sources/CliDocCore/Documentation.docc/Resources/group.png
LFS
Normal file
Binary file not shown.
@@ -2,6 +2,23 @@
|
|||||||
///
|
///
|
||||||
/// This allows you to group content together, which can optionally be
|
/// This allows you to group content together, which can optionally be
|
||||||
/// styled.
|
/// styled.
|
||||||
|
///
|
||||||
|
/// ### Example:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// let group = Group {
|
||||||
|
/// "My headline."
|
||||||
|
/// "\n"
|
||||||
|
/// "Some content".color(.green)
|
||||||
|
/// "\n"
|
||||||
|
/// "Foo Bar".italic()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// print(group.render())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
public struct Group<Content: TextNode>: TextNode {
|
public struct Group<Content: TextNode>: TextNode {
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public extension HStack {
|
|||||||
/// Style a ``HStack`` by creating a type that conforms to ``HStackStyle`` and use the
|
/// Style a ``HStack`` by creating a type that conforms to ``HStackStyle`` and use the
|
||||||
/// style by calling the ``HStack/style(_:)`` method on your instance.
|
/// style by calling the ``HStack/style(_:)`` method on your instance.
|
||||||
///
|
///
|
||||||
public protocol HStackStyle: TextModifier where Content == StackConfiguration {}
|
public protocol HStackStyle: TextModifier where Content == _StackConfiguration {}
|
||||||
|
|
||||||
public extension HStackStyle where Self == HStackSeparatorStyle {
|
public extension HStackStyle where Self == HStackSeparatorStyle {
|
||||||
/// Apply the given separator on a ``HStack``.
|
/// Apply the given separator on a ``HStack``.
|
||||||
@@ -88,7 +88,7 @@ public struct HStackSeparatorStyle: HStackStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func render(content: StackConfiguration) -> some TextNode {
|
public func render(content: _StackConfiguration) -> some TextNode {
|
||||||
AnySeparatableStackNode(content: content, separator: separator)
|
AnySeparatableStackNode(content: content, separator: separator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
// swiftlint:disable type_name
|
||||||
/// Represents the content of an ``HStack`` or a ``VStack``.
|
/// Represents the content of an ``HStack`` or a ``VStack``.
|
||||||
///
|
///
|
||||||
///
|
/// This is an internal convenience type, but needs to remain public
|
||||||
public struct StackConfiguration {
|
/// for protcol conformances to work properly.
|
||||||
|
public struct _StackConfiguration {
|
||||||
public let content: [any TextNode]
|
public let content: [any TextNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable type_name
|
||||||
|
|
||||||
/// A helper type that removes empty text nodes, and applies a separtor between
|
/// A helper type that removes empty text nodes, and applies a separtor between
|
||||||
/// the array of text nodes.
|
/// the array of text nodes.
|
||||||
///
|
///
|
||||||
@@ -18,7 +22,7 @@ struct AnySeparatableStackNode<Separator: TextNode>: TextNode {
|
|||||||
let separator: Separator
|
let separator: Separator
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
init(content: StackConfiguration, separator: Separator) {
|
init(content: _StackConfiguration, separator: Separator) {
|
||||||
self.content = content.content
|
self.content = content.content
|
||||||
self.separator = separator
|
self.separator = separator
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public extension VStack {
|
|||||||
/// Style a ``VStack`` by creating a type that conforms to ``VStackStyle`` and use the
|
/// Style a ``VStack`` by creating a type that conforms to ``VStackStyle`` and use the
|
||||||
/// style by calling the ``VStack/style(_:)`` method on your instance.
|
/// style by calling the ``VStack/style(_:)`` method on your instance.
|
||||||
///
|
///
|
||||||
public protocol VStackStyle: TextModifier where Content == StackConfiguration {}
|
public protocol VStackStyle: TextModifier where Content == _StackConfiguration {}
|
||||||
|
|
||||||
public extension VStackStyle where Self == VStackSeparatorStyle {
|
public extension VStackStyle where Self == VStackSeparatorStyle {
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ public struct VStackSeparatorStyle: VStackStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func render(content: StackConfiguration) -> some TextNode {
|
public func render(content: _StackConfiguration) -> some TextNode {
|
||||||
AnySeparatableStackNode(content: content, separator: separator)
|
AnySeparatableStackNode(content: content, separator: separator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,26 @@ struct CliDocCoreTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#expect(group.render() == "foobar\("baz".blue)")
|
#expect(group.render() == "foobar\("baz".blue)")
|
||||||
|
|
||||||
|
let group2 = Group {
|
||||||
|
VStack {
|
||||||
|
"My headline."
|
||||||
|
"Some text."
|
||||||
|
}
|
||||||
|
"\n"
|
||||||
|
HStack {
|
||||||
|
"Foo"
|
||||||
|
"Bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.color(.green)
|
||||||
|
|
||||||
|
print(group2.render())
|
||||||
|
#expect(group2.render() == """
|
||||||
|
My headline.
|
||||||
|
Some text.
|
||||||
|
Foo Bar
|
||||||
|
""".green)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user