<$head_tag>$sym_name$hash_link$head_tag>')
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