Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
helje5 committed Jul 6, 2021
2 parents cc8e5a9 + 34a0d09 commit 189c569
Show file tree
Hide file tree
Showing 24 changed files with 725 additions and 29 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ open file:/tmp/SlothCreatorSite/documentation/slothcreator.html

## Status

### 2021-07-06

Well, it's getting closer and the source code starts to be quite
reasonable as well. Though you can still tell it started as a
quick hack.

### 2021-07-03

**It's not ready for production yet, needs some more work.**

This is a very quick hack/PoC full of quirks,
Expand All @@ -53,10 +61,10 @@ It's not much yet, but a pretty good starting point.

## TODO

- [ ] better templates
- [ ] support tutorials (task sections etc)
- [ ] better API doc templates
- [ ] improve tutorial templates
- [ ] better CSS
- [ ] refactor code into a proper type and module for easier reuse
- [x] refactor code into a proper type and module for easier reuse
- [x] drop dependency on Macro
- [ ] support Mustache templates in the filesystem! (for customization & faster testing)

Expand Down
3 changes: 2 additions & 1 deletion Sources/DocCHTMLExporter/DZRenderingContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ open class DZRenderingContext {
}

public struct Templates {
// refer to them using this struct, to make them configurable later on.

public init() {}

/// Arguments:
/// relativePathToRoot, highlightCDN, contentHTML, footerHTML, title,
Expand Down
25 changes: 25 additions & 0 deletions Sources/DocCHTMLExporter/Templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h2>docc2html Templates (Code)
<img src="http://zeezide.com/img/docz/docc2html100.png"
align="right" width="100" height="100" />
</h2>

This folder contains the default Mustache templates used,
plus the `Site.css` containing the default CSS.

It is used as a fallback if the `Templates` (resource) directory in the package root cannot
be reached, or not `-t/--templates` option was specified.
When PR'ing changes, please do so in the resource directory.


### Who

**docc2html** is brought to you by
the
[Always Right Institute](http://www.alwaysrightinstitute.com)
and
[ZeeZide](http://zeezide.de).
We like
[feedback](https://twitter.com/ar_institute),
GitHub stars,
cool [contract work](http://zeezide.com/en/services/services.html),
presumably any form of praise you can think of.
20 changes: 14 additions & 6 deletions Sources/DocCStaticExporter/DocCStaticExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,22 @@ open class DocCStaticExporter {
public let options : Options
public let target : DocCStaticExportTarget
public let archiveURLs : [ URL ]
public let stylesheet = DZRenderingContext.defaultStyleSheet

public let stylesheet : String
public let templates : DZRenderingContext.Templates?

public var dataFolderPathes = Set<String>()

public init(target: DocCStaticExportTarget, archivePathes: [ String ],
options: Options, logger: Logger = Logger(label: "docc2html"))
public init(target : DocCStaticExportTarget, archivePathes: [ String ],
options : Options,
templates : DZRenderingContext.Templates? = nil,
stylesheet : String? = nil,
logger : Logger = Logger(label: "docc2html"))
{
self.target = target
self.archiveURLs = archivePathes.map(URL.init(fileURLWithPath:))
self.options = options
self.templates = templates
self.stylesheet = stylesheet ?? DZRenderingContext.defaultStyleSheet
self.logger = logger
}

Expand Down Expand Up @@ -170,7 +176,8 @@ open class DocCStaticExporter {
references : document.references,
isIndex : true,
dataFolderPathes : dataFolderPathes,
indexLinks : true
indexLinks : true,
templates : templates
)

let html = try ctx.buildDocument(document, in: folder)
Expand All @@ -191,7 +198,8 @@ open class DocCStaticExporter {
references : document.references,
isIndex : false,
dataFolderPathes : dataFolderPathes,
indexLinks : buildIndex
indexLinks : buildIndex,
templates : templates
)

let html = try ctx.buildDocument(document, in: folder)
Expand Down
1 change: 1 addition & 0 deletions Sources/docc2html/ExitCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum ExitCode: Int32, Swift.Error {
case targetDirectoryExists = 4
case couldNotLoadStaticResource = 5
case couldNotCopyStaticResource = 6
case couldNotFindTemplatesDir = 7
}

extension ExitCode {
Expand Down
60 changes: 60 additions & 0 deletions Sources/docc2html/LoadTemplates.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// LoadTemplates.swift
// docc2html
//
// Created by Helge Heß.
// Copyright © 2021 ZeeZide GmbH. All rights reserved.
//

import mustache
import Foundation
import DocCHTMLExporter // @docczz/docc2html

func loadTemplatesAndStylesheet(from path: String)
-> ( templates: DZRenderingContext.Templates, stylesheet: String )
{
let baseURL = URL(fileURLWithPath: path)
let cssURL = baseURL.appendingPathComponent("site.css")

let stylesheet = (try? String(contentsOf: cssURL))
?? DZRenderingContext.defaultStyleSheet

var templates = DZRenderingContext.Templates()

func load(_ name: String) -> Mustache? {
let url = baseURL.appendingPathComponent(name)
.appendingPathExtension("mustache")
guard FileManager.default.fileExists(atPath: url.path) else {
logger.trace("No filesystem template for:", name)
return nil
}

do {
let s = try String(contentsOf: url)
let m = Mustache(s)
logger.trace("Did load template:", name, "from:", url.path)
return m
}
catch {
logger.error("Failed to load template:", name, error)
return nil
}
}

if let m = load("Page") { templates.htmlWrapper = m }
if let m = load("DocumentContent") { templates.documentContent = m }
if let m = load("Navigation") { templates.navigation = m }
if let m = load("PrimaryContent") { templates.primaryContentGrid = m }
if let m = load("CodeListing") { templates.codeListing = m }
if let m = load("StepContent") { templates.step = m }
if let m = load("DeclarationSection") { templates.declarationSection = m }
if let m = load("ParametersSection") { templates.parametersSection = m }
if let m = load("Sections") { templates.contentTableSection = m }
if let m = load("TopicTitle") { templates.topicTitle = m }
if let m = load("Hero") { templates.hero = m }
if let m = load("Task") { templates.task = m }
if let m = load("TaskIntro") { templates.taskIntro = m }
if let m = load("Volume") { templates.volume = m }

return ( templates: templates, stylesheet: stylesheet )
}
71 changes: 53 additions & 18 deletions Sources/docc2html/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ func usage() {
Options:
-f/--force: overwrite/merge target directories and files
-s/--silent: silent logging
-v/--verbose: verbose logging
--keep-hash: keep hashes in resource names
--copy-css: copy the CSS folder in the archive to the target
-f/--force: overwrite/merge target directories and files
-s/--silent: silent logging
-v/--verbose: verbose logging
-t/--templates <directory>: directory containing template files
"""
)
}
Expand All @@ -39,28 +38,64 @@ struct Options {
= [ .buildIndex, .buildAPIDocs, .buildTutorials ]
let archivePathes : [ String ]
let targetPath : String
let templatesPath : String?
let logFactory : ( String ) -> LogHandler

var targetURL : URL { URL(fileURLWithPath: targetPath) }

init?(argv: [ String ]) {
if argv.contains("--force") || argv.contains("-f") {
exportOptions.insert(.force)
var argv = argv

func processFlag(_ long: String, _ short: String = "") -> Bool {
let ok = argv.contains(long)
|| (short.isEmpty ? false : argv.contains(short))
argv.removeAll(where: { $0 == long || $0 == short })
return ok
}
if argv.contains("--keep-hash") { exportOptions.insert(.keepHash ) }
if argv.contains("--copy-css") { exportOptions.insert(.copySystemCSS) }

let silent = argv.contains("--silent") || argv.contains("-s")
let verbose = argv.contains("--verbose") || argv.contains("-v")

logFactory = { label in
var handler = StreamLogHandler.standardOutput(label: label)
if verbose { handler.logLevel = .trace }
else if silent { handler.logLevel = .error }
return handler
if processFlag("--force", "-f") { exportOptions.insert(.force ) }
if processFlag("--keep-hash") { exportOptions.insert(.keepHash ) }
if processFlag("--copy-css") { exportOptions.insert(.copySystemCSS) }

if let idx = argv.firstIndex(of: "-t")
?? argv.firstIndex(of: "--templates"),
(idx + 1) < argv.count
{
argv.remove(at: idx)
templatesPath = argv[idx]
argv.remove(at: idx)
}
else {
let binURL = URL(fileURLWithPath: #filePath)
let pkgURL = binURL.deletingLastPathComponent()
.deletingLastPathComponent()
.deletingLastPathComponent()
let url = pkgURL.appendingPathComponent("Templates")
var isDir : ObjCBool = false
let fm = FileManager.default
if fm.fileExists(atPath: url.path, isDirectory: &isDir), isDir.boolValue {
templatesPath = url.path
}
else {
templatesPath = nil
}
}

do { // Logging
let silent = processFlag("--silent", "-s")
let verbose = processFlag("--verbose", "-v")

logFactory = { label in
var handler = StreamLogHandler.standardOutput(label: label)
if verbose { handler.logLevel = .trace }
else if silent { handler.logLevel = .error }
return handler
}
}

let pathes = argv.dropFirst().filter { !$0.hasPrefix("-") }
// TODO: scan for unprocessed `-` and throw an error?

let pathes = argv.dropFirst().filter { !$0.hasPrefix("-") }
guard pathes.count > 1 else { return nil }
archivePathes = Array(pathes.dropLast())
targetPath = pathes.last ?? ""
Expand Down
32 changes: 31 additions & 1 deletion Sources/docc2html/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,48 @@
import Foundation
import Logging // @apple/swift-log
import DocCStaticExporter // @docczz/docc2html
import DocCHTMLExporter // @docczz/docc2html


// MARK: - Process Commandline Arguments and Setup Logging

guard let options = Options(argv: CommandLine.arguments) else {
usage()
exit(ExitCode.notEnoughArguments.rawValue)
}

LoggingSystem.bootstrap(options.logFactory)
let logger = Logger(label: "docc2html")


// MARK: - Load Templates, if available

let templates : DZRenderingContext.Templates?
let stylesheet : String?
if let path = options.templatesPath {
guard FileManager.default.fileExists(atPath: path) else {
logger.error("Did not find templates directory:", path)
exit(ExitCode.couldNotFindTemplatesDir)
}

logger.trace("Using templates directory:", path)
( templates, stylesheet ) = loadTemplatesAndStylesheet(from: path)
}
else {
templates = nil
stylesheet = nil
}


// MARK: - Setup Site Exporter and Run

let exporter = DocCStaticExporter(
target : DocCFileSystemExportTarget(targetPath: options.targetPath),
archivePathes : options.archivePathes,
options : options.exportOptions
options : options.exportOptions,
templates : templates,
stylesheet : stylesheet,
logger : logger
)

do {
Expand Down
6 changes: 6 additions & 0 deletions Templates/CodeListing.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div data-syntax="{{syntax}}" class="code-listing">
<div class="container-general">
<pre><code>{{#lines}}<span class="code-line-container"><span data-line-number="{{{line}}}" class="code-number" style="display: none;"></span><span class="code-line">{{code}}</span></span>
{{/lines}}</code></pre>
</div>
</div>
6 changes: 6 additions & 0 deletions Templates/DeclarationSection.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<section id='declaration' class='declaration'>
<h2>{{title}}</h2>
<div class='declaration-group'>
<pre class='source indented'><code>{{{tokensHTML}}}</code></pre>
</div>
</section>
10 changes: 10 additions & 0 deletions Templates/DocumentContent.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{{navigationHTML}}}
<main id="main" role="main" class="main">
{{{topicTitleHTML}}}
{{{primaryContentHTML}}}
{{#sectionsContentHTML}}
<div class="sections">{{{sectionsContentHTML}}}</div>
{{/sectionsContentHTML}}
{{{topicSectionsHTML}}}
{{{seeAlsoHTML}}}
</main>
29 changes: 29 additions & 0 deletions Templates/Hero.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div id="introduction" class="tutorial-hero">
<div class="hero dark">
{{#backgroundImage}}
<div class="bg"
style="background-image: url(&quot;{{backgroundImage}}&quot;);"></div>
{{/backgroundImage}}

<div class="row">
<div class="col large-7 medium-9 small-12">
<div class="headline"><span class="eyebrow">{{eyebrow}}</span>
<h1 class="heading">{{title}}</h1>
</div>
</div>
<div class="intro">
<div class="content">{{{contentHTML}}}</div>
</div>
<div class="metadata">
<div class="item">
<div class="content">
<div class="duration">{{duration}}
<div class="minutes">min</div>
</div>
</div>
<div class="bottom">Estimated Time</div>
</div>
</div>
</div>
</div>
</div>
Loading

0 comments on commit 189c569

Please sign in to comment.