Skip to content

Commit

Permalink
WIP: implement
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickpeterse committed May 27, 2024
1 parent 86834ba commit 410d108
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 44 deletions.
78 changes: 47 additions & 31 deletions src/idoc/cmd/html.inko
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import idoc.ir (Constant, Module)
import std.fs.file (ReadOnlyFile, WriteOnlyFile)
import idoc.ir (Module)
import std.fs.file (WriteOnlyFile)
import std.fs.path (Path)
import std.io (Write)
import std.json (Error, PullParser)
import std.json (Error)
import std.optparse (Help, Options)
import std.range (InclusiveRange)

# The default directory in which to look for the output of `inko doc`.
#
Expand All @@ -27,6 +26,24 @@ fn usage(options: ref Options, output: mut Write) {
let _ = output.write_string(help)
}

class async Parser {
fn async parse(
input: uni Path,
output: Channel[uni Result[Module, (Path, Error)]],
) {
let res = recover {
let input = recover input

match Module.parse_file(input.clone) {
case Ok(v) -> Result.Ok(v)
case Error(e) -> Result.Error((input, e))
}
}

output.send(res)
}
}

fn run(
arguments: Array[String],
working_directory: ref Path,
Expand All @@ -49,47 +66,46 @@ fn run(

# TODO:
#
# - Parse the JSON files
# - Convert the JSON data to Markdown files, one for each module. Write these
# build/idoc/source/
# - Adjust the headings in examples to be of the right level
# - Wrap documentation headings such that we don't include them in the table
# of contents.
# - Do all this in parallel
# - Copy assets (e.g. CSS) from /usr/share/whatever to build/idoc/source/
# - Generate static website using inko-wobsite, write to build/idoc/public/

let files = try input
.list
.then(fn (iter) {
iter.try_reduce([], fn (acc, res) {
match res {
case Ok({ @path = path, @type = File }) -> {
match path.extension {
case Some('json') -> acc.push(path)
case _ -> {}
}
}
case Error(e) -> throw e
case _ -> {}
}

Result.Ok(acc)
})
})
.map_error(fn (e) { 'failed to get the JSON input files: ${e}' })

let dir = OUTPUT_DIR.to_path
let md_dir = dir.join('source/modules')

try md_dir.create_directory_all.map_error(fn (e) {
"failed to create '${md_dir}': ${e}"
})

try files.into_iter.try_each(fn (path) {
try Module.parse_file(path.clone).map_error(fn (e) {
'failed to parse ${path}: ${e}'
let modules = Channel.new(size: 32)
let pending = try input
.list
.then(fn (iter) {
iter.try_reduce(0, fn (sum, res) {
match res {
case Ok({ @path = p, @type = File }) if p.extension.or('') == 'json'
-> {
Parser().parse(recover p.clone, modules)
Result.Ok(sum + 1)
}
case Ok(_) -> Result.Ok(sum)
case Error(e) -> Result.Error(e)
}
})
})

Result.Ok(nil)
.map_error(fn (e) { 'failed to get the JSON files to process: ${e}' })

# TODO: better error handling of course
# TODO: convert to HTML
pending.times(fn (_) {
match modules.receive {
case Ok(mod) -> output.print('OK: ${mod.name}')
case Error((path, err)) -> output.print('ERR: ${path}: ${err}')
}
})

Result.Ok(nil)
Expand Down
Loading

0 comments on commit 410d108

Please sign in to comment.