import CommandClient import ConfigurationClient import Dependencies import DependenciesMacros import Foundation public extension DependencyValues { /// Represents interactions with the `pandoc` command line application. /// /// The `pandoc` command line application is used to generate the final output /// documents from a home performance assessment project. /// var pandocClient: PandocClient { get { self[PandocClient.self] } set { self[PandocClient.self] = newValue } } } @DependencyClient public struct PandocClient: Sendable { /// Run a pandoc command. public var run: Run /// Represents the pandoc commands that we can run. @DependencyClient public struct Run: Sendable { /// Generate a latex file from the given options, returning the path the /// generated file was written to. public var generateLatex: @Sendable (RunOptions) async throws -> String /// Generate an html file from the given options, returning the path the /// generated file was written to. public var generateHtml: @Sendable (RunOptions) async throws -> String /// Generate a pdf file from the given options, returning the path the /// generated file was written to. public var generatePdf: @Sendable (RunOptions, String?) async throws -> String /// Generate a pdf file from the given options, returning the path the /// generated file was written to. /// /// - Parameters: /// - options: The shared run options. /// - pdfEngine: The pdf-engine to use to generate the pdf file. public func generatePdf( _ options: RunOptions, pdfEngine: String? = nil ) async throws -> String { try await generatePdf(options, pdfEngine) } } /// Represents the shared options used to run a `pandoc` command. /// /// public struct RunOptions: Equatable, Sendable { let buildDirectory: String? let extraOptions: [String]? let files: [String]? let loggingOptions: LoggingOptions let includeInHeader: [String]? let outputDirectory: String? let outputFileName: String? let projectDirectory: String? let quiet: Bool let shell: String? let shouldBuildProject: Bool /// Create the shared run options. /// /// - Parameters: /// - buildDirectory: Specify the build directory of the project. /// - extraOptions: Extra arguments / options passed to the `pandoc` command. /// - file: Files used to build the final output. /// - loggingOptions: The logging options used when running the command. /// - includeInHeader: Files to include in the header of the final output document. /// - outputDirectory: Optional output directory for the output file, defaults to current working directory. /// - projectDirectory: Optional project directory, defaults to current working directory. /// - outputFileName: Override the output file name. /// - quiet: Don't log output from the command. /// - shell: Optional shell to use when calling the pandoc command. /// - shouldBuildProject: Build the project prior to generating the output file. public init( buildDirectory: String? = nil, extraOptions: [String]? = nil, files: [String]? = nil, loggingOptions: LoggingOptions, includeInHeader: [String]? = nil, outputDirectory: String? = nil, projectDirectory: String? = nil, outputFileName: String? = nil, quiet: Bool = false, shell: String? = nil, shouldBuild shouldBuildProject: Bool = true ) { self.buildDirectory = buildDirectory self.extraOptions = extraOptions self.files = files self.loggingOptions = loggingOptions self.includeInHeader = includeInHeader self.outputDirectory = outputDirectory self.outputFileName = outputFileName self.projectDirectory = projectDirectory self.quiet = quiet self.shell = shell self.shouldBuildProject = shouldBuildProject } } /// Represents the file types that we can generate output files for. @_spi(Internal) public enum FileType: Equatable, Sendable { case html case latex case pdf(engine: String?) } } extension PandocClient: DependencyKey { public static let testValue: PandocClient = Self(run: Run()) public static func live(environment: [String: String]) -> PandocClient { .init( run: Run( generateLatex: { try await $0.run(.latex, environment) }, generateHtml: { try await $0.run(.html, environment) }, generatePdf: { try await $0.run(.pdf(engine: $1), environment) } ) ) } public static var liveValue: PandocClient { .live(environment: ProcessInfo.processInfo.environment) } }