From cbcdc8434f0e6c68d8f85bd0b7e0254af41de136 Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Sun, 7 Jun 2020 18:27:42 +0800 Subject: [PATCH] vdoc: group constants + minor fixes --- cmd/tools/vdoc-resources/doc.css | 17 +++++++- cmd/tools/vdoc.v | 69 +++++++++++++++++++++++++------- cmd/v/help/doc.txt | 2 + vlib/v/doc/doc.v | 52 ++++++++++++++++++++---- 4 files changed, 116 insertions(+), 24 deletions(-) diff --git a/cmd/tools/vdoc-resources/doc.css b/cmd/tools/vdoc-resources/doc.css index 6d7f6145ee..0881e14978 100644 --- a/cmd/tools/vdoc-resources/doc.css +++ b/cmd/tools/vdoc-resources/doc.css @@ -266,6 +266,17 @@ body { .doc-content > .doc-node:not(:last-child) { padding: 1rem 0 3rem 0; } +.doc-content > .doc-node.const:not(:first-child) { + padding-top: 0; +} +.doc-content > .doc-node.const:not(:last-child) { + padding-bottom: 1rem; +} +.doc-content > .timestamp { + font-size: 0.8rem; + color: #b8c2cc; + color: var(--timestamp-color); +} .doc-content > .doc-node > .title { display: flex; align-items: center; @@ -385,7 +396,8 @@ body { /* Code highlight */ pre[class*="language-"], -code[class*="language-"] { +code[class*="language-"], +pre code { color: #5c6e74; color: var(--code-default-text-color); font-size: 0.8rem; @@ -410,7 +422,8 @@ code[class*="language-"] { border-radius: 0.25rem; overflow-x: auto; } -code[class*="language-"] { +code[class*="language-"], +pre code { padding: 1rem; } pre[class*="language-"] { diff --git a/cmd/tools/vdoc.v b/cmd/tools/vdoc.v index 712e29b909..8ddad56ec2 100644 --- a/cmd/tools/vdoc.v +++ b/cmd/tools/vdoc.v @@ -54,6 +54,8 @@ mut: is_multi bool = false is_verbose bool = false include_readme bool = false + open_docs bool = false + server_port int = 8046 inline_assets bool = false output_path string input_path string @@ -79,13 +81,16 @@ fn open_url(url string) { } fn (mut cfg DocConfig) serve_html() { + server_url := 'http://localhost:' + cfg.server_port.str() docs := cfg.render() def_name := docs.keys()[0] - server := net.listen(8046) or { + server := net.listen(cfg.server_port) or { panic(err) } - println('Serving docs on: http://localhost:8046') - open_url('http://localhost:8046') + println('Serving docs on: $server_url') + if cfg.open_docs { + open_url(server_url) + } for { con := server.accept() or { server.close() or { } @@ -226,13 +231,14 @@ fn doc_node_html(dd doc.DocNode, link string, head bool, tb &table.Table) string head_tag := if head { 'h1' } else { 'h2' } md_content := markdown.to_html(dd.comment) hlighted_code := html_highlight(dd.content, tb) + is_const_class := if dd.name == 'Constants' { ' const' } else { '' } mut sym_name := dd.name - if dd.parent_type !in ['void', ''] { + if dd.parent_type !in ['void', '', 'Constants'] { sym_name = '${dd.parent_type}.' + sym_name } node_id := slug(sym_name) - hash_link := if head_tag != 'h1' { ' #' } else { '' } - dnw.writeln('
') + hash_link := if !head { ' #' } else { '' } + dnw.writeln('
') if dd.name != 'README' { dnw.write('
<$head_tag>$sym_name$hash_link') if link.len != 0 { @@ -252,7 +258,7 @@ fn doc_node_html(dd doc.DocNode, link string, head bool, tb &table.Table) string fn (cfg DocConfig) gen_html(idx int) string { dcs := cfg.docs[idx] - time_gen := dcs.time_generated.day.str() + ' ' + dcs.time_generated.smonth() + ' ' + dcs.time_generated.year.str() + ' ' + dcs.time_generated.hhmmss() + time_gen := '$dcs.time_generated.day $dcs.time_generated.smonth() $dcs.time_generated.year $dcs.time_generated.hhmmss()' mut hw := strings.new_builder(200) mut toc := strings.new_builder(200) // generate toc first @@ -260,7 +266,7 @@ fn (cfg DocConfig) gen_html(idx int) string { if cn.parent_type !in ['void', ''] { continue } toc.write('
  • ${cn.name}') children := dcs.contents.find_children_of(cn.name) - if children.len != 0 { + if children.len != 0 && cn.name != 'Constants' { toc.writeln('
      ') for child in children { cname := cn.name + '.' + child.name @@ -418,7 +424,7 @@ fn (cfg DocConfig) gen_markdown(idx int, with_toc bool) string { hw.writeln('## Contents') } for cn in dcs.contents { - name := cn.name.all_after(dcs.head.name+'.') + name := cn.name.all_after(dcs.head.name + '.') if with_toc { hw.writeln('- [#$name](${slug(name)})') @@ -458,6 +464,23 @@ fn (cfg DocConfig) render() map[string]string { return docs } +fn (cfg DocConfig) get_readme(path string) string { + mut fname := '' + for name in ['readme', 'README'] { + if os.exists(os.join_path(path, '${name}.md')) { + fname = name + break + } + } + if fname == '' { + return '' + } + readme_path := os.join_path(path, '${fname}.md') + cfg.vprintln('Reading README file from $readme_path') + readme_contents := os.read_file(readme_path) or { '' } + return readme_contents +} + fn (mut cfg DocConfig) generate_docs_from_file() { if cfg.output_path.len == 0 { if cfg.output_type == .unset { @@ -484,16 +507,14 @@ fn (mut cfg DocConfig) generate_docs_from_file() { os.base_dir(cfg.input_path) } manifest_path := os.join_path(dir_path, 'v.mod') - readme_path := os.join_path(dir_path, 'README.md') if os.exists(manifest_path) { cfg.vprintln('Reading v.mod info from $manifest_path') if manifest := vmod.from_file(manifest_path) { cfg.manifest = manifest } } - if os.exists(readme_path) && cfg.include_readme { - cfg.vprintln('Reading README file from $readme_path') - readme_contents := os.read_file(readme_path) or { '' } + if cfg.include_readme { + readme_contents := cfg.get_readme(dir_path) if cfg.output_type == .stdout { println(markdown.to_plain(readme_contents)) } @@ -514,6 +535,10 @@ fn (mut cfg DocConfig) generate_docs_from_file() { panic(err) } if dcs.contents.len == 0 { continue } + if cfg.is_multi { + readme_contents := cfg.get_readme(dirpath) + dcs.head.comment = readme_contents + } if cfg.pub_only { for i, c in dcs.contents { dcs.contents[i].content = c.content.all_after('pub ') @@ -541,7 +566,7 @@ fn (mut cfg DocConfig) generate_docs_from_file() { panic(err) } } else { - for fname in ['doc.css', 'v-prism.css', 'doc.js'] { + for fname in ['doc.css', 'normalize.css' 'doc.js'] { os.rm(os.join_path(cfg.output_path, fname)) } } @@ -668,6 +693,22 @@ fn main() { cfg.output_path = os.real_path(opath) i++ } + '-open' { + cfg.open_docs = true + } + '-p' { + s_port := cmdline.option(current_args, '-o', '') + s_port_int := s_port.int() + if s_port.len == 0 { + eprintln('vdoc: No port number specified on "-p".') + exit(1) + } + if s_port != s_port_int.str() { + eprintln('vdoc: Invalid port number.') + exit(1) + } + cfg.server_port = s_port_int + } '-s' { cfg.inline_assets = true cfg.serve_http = true diff --git a/cmd/v/help/doc.txt b/cmd/v/help/doc.txt index dc359684d5..77bb636bc8 100644 --- a/cmd/v/help/doc.txt +++ b/cmd/v/help/doc.txt @@ -17,6 +17,8 @@ Options: -l Show the locations of the generated signatures. (For plaintext only) -m Generate docs for modules listed in that folder. -o Specifies the output file/folder path where to store the generated docs. + -open Launches the browser when the server docs has started. + -p Specifies the port to be used for the docs server. -s Serve HTML-generated docs via HTTP. -r Include README.md to docs if present. -v Enables verbose logging. For debugging purposes. diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index c61dcdf150..2bfcc6203c 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -57,10 +57,29 @@ pub fn get_comment_block_right_before(stmts []ast.Stmt) string { // located right above the top level statement. // break } - cmt_content := cmt.text.trim_left('|') - if cmt_content.len == cmt.text.len { + mut cmt_content := cmt.text.trim_left('|') + if cmt_content.len == cmt.text.len || cmt.is_multi { // ignore /* */ style comments for now continue + // if cmt_content.len == 0 { + // continue + // } + // mut new_cmt_content := '' + // mut is_codeblock := false + // // println(cmt_content) + // lines := cmt_content.split_into_lines() + // for j, line in lines { + // trimmed := line.trim_space().trim_left(cmt_prefix) + // if trimmed.starts_with('- ') || (trimmed.len >= 2 && trimmed[0].is_digit() && trimmed[1] == `.`) || is_codeblock { + // new_cmt_content += line + '\n' + // } else if line.starts_with('```') { + // is_codeblock = !is_codeblock + // new_cmt_content += line + '\n' + // } else { + // new_cmt_content += trimmed + '\n' + // } + // } + // return new_cmt_content } //eprintln('cmt: $cmt') cseparator := if cmt_content.starts_with('```') {'\n'} else {' '} @@ -87,6 +106,7 @@ pub fn (d Doc) get_signature(stmt ast.Stmt) string { out: strings.new_builder(1000) out_imports: strings.new_builder(200) table: d.table + cur_mod: d.head.name.split('.').last() indent: 0 is_debug: false } @@ -95,7 +115,7 @@ pub fn (d Doc) get_signature(stmt ast.Stmt) string { return 'module $it.name' } ast.FnDecl { - return it.str(d.table) + return it.str(d.table).replace(f.cur_mod + '.', '') } else { f.stmt(stmt) @@ -115,12 +135,22 @@ pub fn (d Doc) get_pos(stmt ast.Stmt) token.Position { } } +pub fn (d Doc) get_type_name(decl ast.TypeDecl) string { + match decl { + ast.SumTypeDecl { return it.name } + ast.FnTypeDecl { return it.name } + ast.AliasTypeDecl { return it.name } + } +} + pub fn (d Doc) get_name(stmt ast.Stmt) string { + cur_mod := d.head.name.split('.').last() match stmt { ast.FnDecl { return it.name } ast.StructDecl { return it.name } ast.EnumDecl { return it.name } ast.InterfaceDecl { return it.name } + ast.TypeDecl { return d.get_type_name(it).replace('&' + cur_mod + '.', '').replace(cur_mod + '.', '') } ast.ConstDecl { return 'Constants' } else { return '' } } @@ -214,6 +244,7 @@ pub fn (mut d Doc) generate() ?bool { mut module_name := '' mut parent_mod_name := '' mut orig_mod_name := '' + mut const_idx := -1 for i, file_ast in file_asts { if i == 0 { parent_mod_name = get_parent_mod(base_path) or { @@ -234,7 +265,7 @@ pub fn (mut d Doc) generate() ?bool { } mut prev_comments := []ast.Stmt{} stmts := file_ast.stmts - for _, stmt in stmts { + for o, stmt in stmts { //eprintln('stmt typeof: ' + typeof(stmt)) if stmt is ast.Comment { prev_comments << stmt @@ -256,11 +287,10 @@ pub fn (mut d Doc) generate() ?bool { d.head.comment += module_comment continue } - // todo: accumulate consts - mut name := d.get_name(stmt) signature := d.get_signature(stmt) pos := d.get_pos(stmt) - if !signature.starts_with('pub') && d.pub_only { + mut name := d.get_name(stmt) + if (!signature.starts_with('pub') && d.pub_only) || stmt is ast.GlobalDecl { prev_comments = [] continue } @@ -283,7 +313,13 @@ pub fn (mut d Doc) generate() ?bool { } node.parent_type = parent_type } - + } + if stmt is ast.ConstDecl { + if const_idx == -1 { + const_idx = o + } else { + node.parent_type = 'Constants' + } } if node.name.len == 0 && node.comment.len == 0 && node.content.len == 0 { continue