feat: Adds more documentation and examples.
All checks were successful
CI / Run tests. (push) Successful in 52s
All checks were successful
CI / Run tests. (push) Successful in 52s
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,3 +8,5 @@ DerivedData/
|
|||||||
.netrc
|
.netrc
|
||||||
.nvim/*
|
.nvim/*
|
||||||
docs/*
|
docs/*
|
||||||
|
Examples/*.png
|
||||||
|
./*.png
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ struct Application: ParsableCommand {
|
|||||||
.init(
|
.init(
|
||||||
commandName: "examples",
|
commandName: "examples",
|
||||||
subcommands: [
|
subcommands: [
|
||||||
SectionCommand.self
|
SectionCommand.self,
|
||||||
|
VStackCommand.self,
|
||||||
|
HStackCommand.self
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
16
Examples/Sources/CliDoc-Examples/HStackCommand.swift
Normal file
16
Examples/Sources/CliDoc-Examples/HStackCommand.swift
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import ArgumentParser
|
||||||
|
import CliDocCore
|
||||||
|
|
||||||
|
struct HStackCommand: ParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(commandName: "hstack")
|
||||||
|
|
||||||
|
func run() throws {
|
||||||
|
let note = HStack {
|
||||||
|
"NOTE:".color(.cyan).bold()
|
||||||
|
"This is my super cool note.".italic()
|
||||||
|
}
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(note.render())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,10 +21,11 @@ struct SectionCommand: ParsableCommand {
|
|||||||
|
|
||||||
struct MySectionStyle: SectionStyle {
|
struct MySectionStyle: SectionStyle {
|
||||||
func render(content: SectionConfiguration) -> some TextNode {
|
func render(content: SectionConfiguration) -> some TextNode {
|
||||||
VStack(separator: .newLine(count: 2)) {
|
VStack {
|
||||||
content.header.color(.green).bold().underline()
|
content.header.color(.green).bold().underline()
|
||||||
content.content
|
content.content
|
||||||
content.footer.italic()
|
content.footer.italic()
|
||||||
}
|
}
|
||||||
|
.separator(.newLine(count: 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
Examples/Sources/CliDoc-Examples/VStackCommand.swift
Normal file
21
Examples/Sources/CliDoc-Examples/VStackCommand.swift
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import ArgumentParser
|
||||||
|
import CliDocCore
|
||||||
|
|
||||||
|
struct VStackCommand: ParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(commandName: "vstack")
|
||||||
|
|
||||||
|
func run() throws {
|
||||||
|
let vstack = VStack {
|
||||||
|
"Blob Esquire"
|
||||||
|
.color(.yellow)
|
||||||
|
.bold()
|
||||||
|
.underline()
|
||||||
|
|
||||||
|
"Blob is a super awesome worker.".italic()
|
||||||
|
}
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(vstack.render())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
|
executable_path := "./.build/release/examples"
|
||||||
|
|
||||||
run command="section":
|
build:
|
||||||
swift run examples {{command}}
|
@swift build -c release
|
||||||
|
|
||||||
|
run command="section": build
|
||||||
|
@{{executable_path}} {{command}}
|
||||||
|
|
||||||
|
snapshot command="section" outputDir="${PWD}": build
|
||||||
|
@freeze --execute "{{executable_path}} {{command}}" \
|
||||||
|
--output {{outputDir}}/"{{command}}.png" \
|
||||||
|
--width 500
|
||||||
|
|||||||
BIN
Sources/CliDocCore/Documentation.docc/Resources/hstack.png
LFS
Normal file
BIN
Sources/CliDocCore/Documentation.docc/Resources/hstack.png
LFS
Normal file
Binary file not shown.
BIN
Sources/CliDocCore/Documentation.docc/Resources/vstack.png
LFS
Normal file
BIN
Sources/CliDocCore/Documentation.docc/Resources/vstack.png
LFS
Normal file
Binary file not shown.
@@ -1,9 +1,28 @@
|
|||||||
/// A horizontal group of text nodes.
|
/// A horizontal stack of text nodes.
|
||||||
|
///
|
||||||
|
/// ### Example:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// let note = HStack {
|
||||||
|
/// "NOTE:".color(.cyan).bold()
|
||||||
|
/// "This is my super cool note".italic()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// print(note.render())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 
|
||||||
|
///
|
||||||
|
///
|
||||||
public struct HStack: TextNode {
|
public struct HStack: TextNode {
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let content: [any TextNode]
|
let content: [any TextNode]
|
||||||
|
|
||||||
|
/// Create a new ``HStack`` with the given text nodes.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - content: The content of the hstack.
|
||||||
@inlinable
|
@inlinable
|
||||||
public init(
|
public init(
|
||||||
@TextBuilder content: () -> any TextNode
|
@TextBuilder content: () -> any TextNode
|
||||||
@@ -18,11 +37,18 @@ public struct HStack: TextNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension HStack {
|
public extension HStack {
|
||||||
|
/// Apply the given style to a ``HStack``.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - style: The style to apply to the ``HStack``.
|
||||||
func style<S: HStackStyle>(_ style: S) -> some TextNode {
|
func style<S: HStackStyle>(_ style: S) -> some TextNode {
|
||||||
style.render(content: .init(content: content))
|
style.render(content: .init(content: content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply the given separator to a ``HStack``.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - separator: The horizontal separator to use with the ``HStack``.
|
||||||
func separator(_ separator: Separator.Horizontal) -> some TextNode {
|
func separator(_ separator: Separator.Horizontal) -> some TextNode {
|
||||||
style(.separator(separator))
|
style(.separator(separator))
|
||||||
}
|
}
|
||||||
@@ -30,16 +56,28 @@ public extension HStack {
|
|||||||
|
|
||||||
// MARK: - Style
|
// MARK: - Style
|
||||||
|
|
||||||
|
/// Style a ``HStack`` by creating a type that conforms to ``HStackStyle`` and use the
|
||||||
|
/// 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``.
|
||||||
|
///
|
||||||
|
/// - See Also: ``HStack/separator(_:)``
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - separator: The vertical separator to use with the ``HStack``.
|
||||||
static func separator(_ separator: Separator.Horizontal) -> Self {
|
static func separator(_ separator: Separator.Horizontal) -> Self {
|
||||||
HStackSeparatorStyle(separator: separator)
|
HStackSeparatorStyle(separator: separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Separate items in a ``HStack`` with a given horizontal separator.
|
||||||
|
///
|
||||||
|
/// - See Also: ``HStack/separator(_:)``.
|
||||||
|
///
|
||||||
public struct HStackSeparatorStyle: HStackStyle {
|
public struct HStackSeparatorStyle: HStackStyle {
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let separator: Separator.Horizontal
|
let separator: Separator.Horizontal
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ public struct StackConfiguration {
|
|||||||
public let content: [any TextNode]
|
public let content: [any TextNode]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper type that removes empty text nodes, and applies a separtor between
|
||||||
|
/// the array of text nodes.
|
||||||
|
///
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
struct AnySeparatableStackNode<Separator: TextNode>: TextNode {
|
struct AnySeparatableStackNode<Separator: TextNode>: TextNode {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
/// A vertical stack of text nodes.
|
/// A vertical stack of text nodes.
|
||||||
///
|
///
|
||||||
|
/// ### Example:
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// let vStack = VStack {
|
||||||
|
/// "Blob Esquire"
|
||||||
|
/// .color(.yellow)
|
||||||
|
/// .bold()
|
||||||
|
/// .underline()
|
||||||
|
///
|
||||||
|
/// "Blob is a super awesome worker.".italic()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// print(vStack.render())
|
||||||
|
/// ```
|
||||||
|
/// 
|
||||||
|
///
|
||||||
///
|
///
|
||||||
public struct VStack: TextNode {
|
public struct VStack: TextNode {
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let content: [any TextNode]
|
let content: [any TextNode]
|
||||||
|
|
||||||
|
/// Create a new ``VStack`` with the given text nodes.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - content: The content of the vstack.
|
||||||
@inlinable
|
@inlinable
|
||||||
public init(
|
public init(
|
||||||
@TextBuilder content: () -> any TextNode
|
@TextBuilder content: () -> any TextNode
|
||||||
@@ -20,10 +40,18 @@ public struct VStack: TextNode {
|
|||||||
|
|
||||||
public extension VStack {
|
public extension VStack {
|
||||||
|
|
||||||
|
/// Apply the given style to a ``VStack``.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - style: The style to apply to the ``VStack``.
|
||||||
func style<S: VStackStyle>(_ style: S) -> some TextNode {
|
func style<S: VStackStyle>(_ style: S) -> some TextNode {
|
||||||
style.render(content: .init(content: content.removingEmptys()))
|
style.render(content: .init(content: content.removingEmptys()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply the given separator to a ``VStack``.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - separator: The vertical separator to use with the ``VStack``.
|
||||||
func separator(_ separator: Separator.Vertical) -> some TextNode {
|
func separator(_ separator: Separator.Vertical) -> some TextNode {
|
||||||
style(.separator(separator))
|
style(.separator(separator))
|
||||||
}
|
}
|
||||||
@@ -31,16 +59,29 @@ public extension VStack {
|
|||||||
|
|
||||||
// MARK: - Style
|
// MARK: - Style
|
||||||
|
|
||||||
|
/// Style a ``VStack`` by creating a type that conforms to ``VStackStyle`` and use the
|
||||||
|
/// 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 {
|
||||||
|
|
||||||
|
/// Apply the given separator on a ``VStack``.
|
||||||
|
///
|
||||||
|
/// - See Also: ``VStack/separator(_:)``
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - separator: The vertical separator to use with the ``VStack``.
|
||||||
static func separator(_ separator: Separator.Vertical) -> Self {
|
static func separator(_ separator: Separator.Vertical) -> Self {
|
||||||
VStackSeparatorStyle(separator: separator)
|
VStackSeparatorStyle(separator: separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Separate items in a ``VStack`` with a given vertical separator.
|
||||||
|
///
|
||||||
|
/// - See Also: ``VStack/separator(_:)``.
|
||||||
|
///
|
||||||
public struct VStackSeparatorStyle: VStackStyle {
|
public struct VStackSeparatorStyle: VStackStyle {
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let separator: Separator.Vertical
|
let separator: Separator.Vertical
|
||||||
|
|||||||
3
justfile
3
justfile
@@ -7,6 +7,9 @@ default:
|
|||||||
clean:
|
clean:
|
||||||
@rm -rf .build
|
@rm -rf .build
|
||||||
|
|
||||||
|
snapshot command outputDir="./Sources/CliDocCore/Documentation.docc/Resources":
|
||||||
|
@just -f Examples/justfile snapshot {{command}} ".{{outputDir}}"
|
||||||
|
|
||||||
test-docker: build-docker
|
test-docker: build-docker
|
||||||
@docker run -t --rm {{docker_image_name}}:test swift test
|
@docker run -t --rm {{docker_image_name}}:test swift test
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user