feat: Adds more documentation and examples.
All checks were successful
CI / Run tests. (push) Successful in 52s

This commit is contained in:
2024-12-08 18:27:31 -05:00
parent c6a269f062
commit 78a632c3e5
12 changed files with 149 additions and 7 deletions

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ DerivedData/
.netrc .netrc
.nvim/* .nvim/*
docs/* docs/*
Examples/*.png
./*.png

View File

@@ -7,7 +7,9 @@ struct Application: ParsableCommand {
.init( .init(
commandName: "examples", commandName: "examples",
subcommands: [ subcommands: [
SectionCommand.self SectionCommand.self,
VStackCommand.self,
HStackCommand.self
] ]
) )
} }

View 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())
}
}

View File

@@ -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))
} }
} }

View 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())
}
}

View File

@@ -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

Binary file not shown.

Binary file not shown.

View File

@@ -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())
/// ```
///
/// ![HStack example](hstack.png)
///
///
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

View File

@@ -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 {

View File

@@ -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())
/// ```
/// ![VStack rendered output](vstack.png)
///
/// ///
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

View File

@@ -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