mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
vdoc: fix syntax highlighting for symbols before !
and between (
and ,
(#19888)
This commit is contained in:
parent
c9429f3331
commit
4458e49652
8
TESTS.md
8
TESTS.md
@ -185,3 +185,11 @@ tests in the main V repository, for example:
|
||||
|
||||
* `v vet vlib/v` - run a style checker.
|
||||
* `v test-self` (run self tests) in various compilation modes.
|
||||
|
||||
> **Note**
|
||||
The VDOC test vdoc_file_test.v now also supports VAUTOFIX, which is
|
||||
useful, if you change anything inside cmd/tools/vdoc or vlib/v/doc/,
|
||||
or inside the modules that it depends on (like markdown).
|
||||
After such changes, just run this command *2 times*, and commit the
|
||||
resulting changes in `cmd/tools/vdoc/tests/testdata` as well:
|
||||
`VAUTOFIX=1 ./v cmd/tools/vdoc/tests/vdoc_file_test.v`
|
||||
|
3
cmd/tools/vdoc/.gitattributes
vendored
Normal file
3
cmd/tools/vdoc/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.ansi text eol=lf
|
||||
*.text text eol=lf
|
||||
*.html text eol=lf
|
@ -198,11 +198,14 @@ fn (vd VDoc) gen_html(d doc.Doc) string {
|
||||
}
|
||||
for cn in dcs_contents {
|
||||
vd.write_content(&cn, &d, mut contents)
|
||||
write_toc(cn, mut symbols_toc)
|
||||
} // write head
|
||||
write_toc(cn, mut symbols_toc) // write head
|
||||
}
|
||||
if cfg.html_only_contents {
|
||||
// no need for theming, styling etc, useful for testing and for external documentation generators
|
||||
return contents.str()
|
||||
}
|
||||
|
||||
// write css
|
||||
mut version := if vd.manifest.version.len != 0 { vd.manifest.version } else { '' }
|
||||
version = [version, @VCURRENTHASH].join(' ')
|
||||
header_name := if cfg.is_multi && vd.docs.len > 1 {
|
||||
os.file_name(os.real_path(cfg.input_path))
|
||||
} else {
|
||||
@ -249,33 +252,65 @@ fn (vd VDoc) gen_html(d doc.Doc) string {
|
||||
}
|
||||
modules_toc_str := modules_toc.str()
|
||||
symbols_toc_str := symbols_toc.str()
|
||||
result := (os.read_file(os.join_path(cfg.theme_dir, 'index.html')) or { panic(err) }).replace('{{ title }}',
|
||||
d.head.name).replace('{{ head_name }}', header_name).replace('{{ version }}',
|
||||
version).replace('{{ light_icon }}', vd.assets['light_icon']).replace('{{ dark_icon }}',
|
||||
vd.assets['dark_icon']).replace('{{ menu_icon }}', vd.assets['menu_icon']).replace('{{ head_assets }}',
|
||||
if cfg.inline_assets {
|
||||
'<style>${vd.assets['doc_css']}</style>
|
||||
mut result := os.read_file(os.join_path(cfg.theme_dir, 'index.html')) or { panic(err) }
|
||||
if cfg.html_no_vhash {
|
||||
result = result.replace('{{ version }}', 'latest')
|
||||
} else {
|
||||
mut version := if vd.manifest.version.len != 0 { vd.manifest.version } else { '' }
|
||||
version = [version, @VCURRENTHASH].join(' ')
|
||||
result = result.replace('{{ version }}', version)
|
||||
}
|
||||
result = result.replace('{{ title }}', d.head.name)
|
||||
result = result.replace('{{ head_name }}', header_name)
|
||||
result = result.replace('{{ light_icon }}', vd.assets['light_icon'])
|
||||
result = result.replace('{{ dark_icon }}', vd.assets['dark_icon'])
|
||||
result = result.replace('{{ menu_icon }}', vd.assets['menu_icon'])
|
||||
if cfg.html_no_assets {
|
||||
result = result.replace('{{ head_assets }}', '')
|
||||
} else {
|
||||
result = result.replace('{{ head_assets }}', if cfg.inline_assets {
|
||||
'<style>${vd.assets['doc_css']}</style>
|
||||
${tabs(2)}<style>${vd.assets['normalize_css']}</style>
|
||||
${tabs(2)}<script>${vd.assets['dark_mode_js']}</script>'
|
||||
} else {
|
||||
'<link rel="stylesheet" href="${vd.assets['doc_css']}" />
|
||||
} else {
|
||||
'<link rel="stylesheet" href="${vd.assets['doc_css']}" />
|
||||
${tabs(2)}<link rel="stylesheet" href="${vd.assets['normalize_css']}" />
|
||||
${tabs(2)}<script src="${vd.assets['dark_mode_js']}"></script>'
|
||||
}).replace('{{ toc_links }}', if cfg.is_multi || vd.docs.len > 1 {
|
||||
modules_toc_str
|
||||
})
|
||||
}
|
||||
if cfg.html_no_toc_urls {
|
||||
result = result.replace('{{ toc_links }}', '')
|
||||
} else {
|
||||
symbols_toc_str
|
||||
}).replace('{{ contents }}', contents.str()).replace('{{ right_content }}', if cfg.is_multi
|
||||
&& d.head.name != 'README' {
|
||||
'<div class="doc-toc"><ul>${symbols_toc_str}</ul></div>'
|
||||
result = result.replace('{{ toc_links }}', if cfg.is_multi || vd.docs.len > 1 {
|
||||
modules_toc_str
|
||||
} else {
|
||||
symbols_toc_str
|
||||
})
|
||||
}
|
||||
result = result.replace('{{ contents }}', contents.str())
|
||||
if cfg.html_no_right {
|
||||
result = result.replace('{{ right_content }}', '')
|
||||
} else {
|
||||
''
|
||||
}).replace('{{ footer_content }}', gen_footer_text(d, !cfg.no_timestamp)).replace('{{ footer_assets }}',
|
||||
if cfg.inline_assets {
|
||||
'<script>${vd.assets['doc_js']}</script>'
|
||||
result = result.replace('{{ right_content }}', if cfg.is_multi && d.head.name != 'README' {
|
||||
'<div class="doc-toc"><ul>${symbols_toc_str}</ul></div>'
|
||||
} else {
|
||||
''
|
||||
})
|
||||
}
|
||||
if cfg.html_no_footer {
|
||||
result = result.replace('{{ footer_content }}', '')
|
||||
} else {
|
||||
'<script src="${vd.assets['doc_js']}"></script>'
|
||||
})
|
||||
result = result.replace('{{ footer_content }}', gen_footer_text(d, !cfg.no_timestamp))
|
||||
}
|
||||
if cfg.html_no_assets {
|
||||
result = result.replace('{{ footer_assets }}', '')
|
||||
} else {
|
||||
result = result.replace('{{ footer_assets }}', if cfg.inline_assets {
|
||||
'<script>${vd.assets['doc_js']}</script>'
|
||||
} else {
|
||||
'<script src="${vd.assets['doc_js']}"></script>'
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,36 @@ const vexe = os.getenv_opt('VEXE') or { @VEXE }
|
||||
|
||||
const vroot = os.dir(vexe)
|
||||
|
||||
const allowed_formats = ['md', 'markdown', 'json', 'text', 'stdout', 'html', 'htm']
|
||||
const allowed_formats = ['md', 'markdown', 'json', 'text', 'ansi', 'html', 'htm']
|
||||
|
||||
struct Config {
|
||||
mut:
|
||||
pub_only bool = true
|
||||
show_loc bool // for plaintext
|
||||
is_color bool
|
||||
is_multi bool
|
||||
is_vlib bool
|
||||
is_verbose bool
|
||||
include_readme bool
|
||||
include_examples bool = true
|
||||
include_comments bool // for plaintext
|
||||
inline_assets bool
|
||||
theme_dir string = default_theme
|
||||
no_timestamp bool
|
||||
output_path string
|
||||
output_type OutputType = .unset
|
||||
input_path string
|
||||
symbol_name string
|
||||
platform doc.Platform
|
||||
run_examples bool // `-run-examples` will run all `// Example: assert mod.abc() == y` comments in the processed modules
|
||||
// The options below are useful for generating a more stable HMTL, that is easier to regression test:
|
||||
html_only_contents bool // `-html-only-contents` will produce only the content of any given page, without styling tags etc.
|
||||
html_no_vhash bool // `-html-no-vhash` will remove the version hash from the generated html
|
||||
html_no_assets bool // `-html-no-assets` will not include CSS and JS asset tags in the generated html
|
||||
html_no_right bool // `-html-no-right` will not add the doc-toc right panel in the generated html
|
||||
html_no_toc_urls bool // `-html-no-toc-urls` will not add the toc_links panel in the generated html
|
||||
html_no_footer bool // `-html-no-footer` will not add the footer panel in the generated html
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if os.args.len < 2 || '-h' in os.args || '-help' in os.args || '--help' in os.args
|
||||
@ -27,9 +56,7 @@ fn main() {
|
||||
// Config is immutable from this point on
|
||||
mut vd := &VDoc{
|
||||
cfg: cfg
|
||||
manifest: vmod.Manifest{
|
||||
repo_url: ''
|
||||
}
|
||||
manifest: vmod.Manifest{}
|
||||
}
|
||||
vd.vprintln('Setting output type to "${cfg.output_type}"')
|
||||
vd.generate_docs_from_file()
|
||||
@ -50,6 +77,7 @@ fn main() {
|
||||
fn parse_arguments(args []string) Config {
|
||||
mut cfg := Config{}
|
||||
cfg.is_color = term.can_show_color_on_stdout()
|
||||
mut is_color_was_set_explicitly := false
|
||||
for i := 0; i < args.len; i++ {
|
||||
arg := args[i]
|
||||
current_args := args[i..]
|
||||
@ -69,9 +97,11 @@ fn parse_arguments(args []string) Config {
|
||||
}
|
||||
'-color' {
|
||||
cfg.is_color = true
|
||||
is_color_was_set_explicitly = true
|
||||
}
|
||||
'-no-color' {
|
||||
cfg.is_color = false
|
||||
is_color_was_set_explicitly = true
|
||||
}
|
||||
'-inline-assets' {
|
||||
cfg.inline_assets = true
|
||||
@ -90,7 +120,7 @@ fn parse_arguments(args []string) Config {
|
||||
}
|
||||
'-o' {
|
||||
opath := cmdline.option(current_args, '-o', '')
|
||||
cfg.output_path = if opath == 'stdout' { opath } else { os.real_path(opath) }
|
||||
cfg.output_path = if opath in ['stdout', '-'] { opath } else { os.real_path(opath) }
|
||||
i++
|
||||
}
|
||||
'-os' {
|
||||
@ -115,6 +145,26 @@ fn parse_arguments(args []string) Config {
|
||||
'-no-examples' {
|
||||
cfg.include_examples = false
|
||||
}
|
||||
//
|
||||
'-html-only-contents' {
|
||||
cfg.html_only_contents = true
|
||||
}
|
||||
'-html-no-vhash' {
|
||||
cfg.html_no_vhash = true
|
||||
}
|
||||
'-html-no-assets' {
|
||||
cfg.html_no_assets = true
|
||||
}
|
||||
'-html-no-right' {
|
||||
cfg.html_no_right = true
|
||||
}
|
||||
'-html-no-toc-urls' {
|
||||
cfg.html_no_toc_urls = true
|
||||
}
|
||||
'-html-no-footer' {
|
||||
cfg.html_no_footer = true
|
||||
}
|
||||
//
|
||||
'-readme' {
|
||||
cfg.include_readme = true
|
||||
}
|
||||
@ -135,28 +185,42 @@ fn parse_arguments(args []string) Config {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Correct from configuration from user input
|
||||
if cfg.output_path == 'stdout' && cfg.output_type == .html {
|
||||
cfg.inline_assets = true
|
||||
|
||||
if cfg.output_type == .html {
|
||||
// quirks specific to *just* the html output mode:
|
||||
if cfg.output_path in ['stdout', '-'] {
|
||||
cfg.inline_assets = true
|
||||
}
|
||||
}
|
||||
$if windows {
|
||||
cfg.input_path = cfg.input_path.replace('/', os.path_separator)
|
||||
} $else {
|
||||
cfg.input_path = cfg.input_path.replace('\\', os.path_separator)
|
||||
|
||||
if !is_color_was_set_explicitly {
|
||||
if cfg.output_type == .plaintext {
|
||||
cfg.is_color = false
|
||||
} else if cfg.output_type == .ansi {
|
||||
cfg.is_color = true
|
||||
}
|
||||
}
|
||||
is_path := cfg.input_path.ends_with('.v') || cfg.input_path.split(os.path_separator).len > 1
|
||||
|
||||
if cfg.is_color {
|
||||
os.setenv('VCOLORS', 'always', true)
|
||||
} else {
|
||||
os.setenv('VCOLORS', 'never', true)
|
||||
}
|
||||
|
||||
cfg.input_path = cfg.input_path.replace('\\', '/')
|
||||
is_path := cfg.input_path.ends_with('.v') || cfg.input_path.split('/').len > 1
|
||||
|| cfg.input_path == '.'
|
||||
if cfg.input_path.trim_right('/') == 'vlib' {
|
||||
cfg.is_vlib = true
|
||||
cfg.is_multi = true
|
||||
cfg.input_path = os.join_path(vroot, 'vlib')
|
||||
} else if !is_path {
|
||||
// TODO vd.vprintln('Input "$cfg.input_path" is not a valid path. Looking for modules named "$cfg.input_path"...')
|
||||
mod_path := doc.lookup_module(cfg.input_path) or {
|
||||
eprintln('vdoc: ${err}')
|
||||
exit(1)
|
||||
}
|
||||
cfg.input_path = mod_path
|
||||
}
|
||||
cfg.input_path = cfg.input_path.replace('/', os.path_separator)
|
||||
return cfg
|
||||
}
|
||||
|
@ -19,4 +19,4 @@ fn funky()
|
||||
|
||||
| foo bar | yes |
|
||||
|-----------|--------|
|
||||
| working | yup |
|
||||
| working | yup |
|
||||
|
@ -1,3 +1,3 @@
|
||||
module main
|
||||
|
||||
fn funky()
|
||||
fn funky()
|
||||
|
36
cmd/tools/vdoc/tests/testdata/output_formats/main.ansi
vendored
Normal file
36
cmd/tools/vdoc/tests/testdata/output_formats/main.ansi
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
[94mmodule[39m [32mmain[39m
|
||||
|
||||
[94mconst[39m omega = [94m3[39m [90m// should be first[39m
|
||||
[94mconst[39m alpha = [94m5[39m [90m// should be in the middle[39m
|
||||
[94mconst[39m beta = [94m2[39m [90m// should be at the end[39m
|
||||
[94mfn[39m [36mabc[39m()
|
||||
abc - should be last
|
||||
[94mfn[39m [36mdef[39m()
|
||||
def - should be first
|
||||
[94mfn[39m [36mxyz[39m()
|
||||
xyz - should be in the middle
|
||||
[94mfn[39m [32mMyXMLDocument[39m.[36mabc[39m(text [32mstring[39m) ?([32mstring[39m, [32mint[39m)
|
||||
MyXMLDocument.abc does something too... I just do not know what.
|
||||
[94mfn[39m [32mMyXMLDocument[39m.[36mfrom_file[39m(path [32mstring[39m) ![32mMyXMLDocument[39m
|
||||
MyXMLDocument.from_text processes the file path, and returns an error
|
||||
[94mfn[39m [32mMyXMLDocument[39m.[36mfrom_text[39m(text [32mstring[39m) ?[32mMyXMLDocument[39m
|
||||
MyXMLDocument.from_text processes text and produces none
|
||||
[94mstruct[39m [32mMyXMLDocument[39m {
|
||||
path [32mstring[39m
|
||||
}
|
||||
MyXMLDocument is here just to test the different combinations of methods/output types
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_from_file[39m(path [32mstring[39m) ![32mMyXMLDocument[39m
|
||||
instance_from_file does stuff with path
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_from_text[39m(text [32mstring[39m) ?[32mMyXMLDocument[39m
|
||||
instance_from_text does stuff with text
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_abc[39m(text [32mstring[39m) ?([32mstring[39m, [32mint[39m)
|
||||
instance_abc does stuff too
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_void[39m()
|
||||
instance_void does stuff too
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_int[39m() [32mint[39m
|
||||
instance_int does stuff too
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_result[39m() !
|
||||
instance_error does stuff too
|
||||
[94mfn[39m (x &[32mMyXMLDocument[39m) [36minstance_option[39m() ?
|
||||
instance_option does stuff too
|
96
cmd/tools/vdoc/tests/testdata/output_formats/main.html
vendored
Normal file
96
cmd/tools/vdoc/tests/testdata/output_formats/main.html
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<section id="readme_main" class="doc-node">
|
||||
<div class="title"><h1> main <a href="#readme_main">#</a></h1></div>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="Constants" class="doc-node const">
|
||||
<div class="title"><h2>Constants <a href="#Constants">#</a></h2></div>
|
||||
|
||||
</section>
|
||||
<section id="" class="doc-node const">
|
||||
<pre class="signature"><code><span class="token keyword">const</span> omega <span class="token operator">=</span> <span class="token number">3</span> <span class="token comment">// should be first</span></code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
<section id="" class="doc-node const">
|
||||
<pre class="signature"><code><span class="token keyword">const</span> alpha <span class="token operator">=</span> <span class="token number">5</span> <span class="token comment">// should be in the middle</span></code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
<section id="" class="doc-node const">
|
||||
<pre class="signature"><code><span class="token keyword">const</span> beta <span class="token operator">=</span> <span class="token number">2</span> <span class="token comment">// should be at the end</span></code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
<section id="abc" class="doc-node">
|
||||
<div class="title"><h2>fn abc <a href="#abc">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token function">abc</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>abc - should be last</p>
|
||||
|
||||
</section>
|
||||
<section id="def" class="doc-node">
|
||||
<div class="title"><h2>fn def <a href="#def">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token function">def</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>def - should be first</p>
|
||||
|
||||
</section>
|
||||
<section id="xyz" class="doc-node">
|
||||
<div class="title"><h2>fn xyz <a href="#xyz">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token function">xyz</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>xyz - should be in the middle</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.abc" class="doc-node">
|
||||
<div class="title"><h2>fn MyXMLDocument.abc <a href="#MyXMLDocument.abc">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> MyXMLDocument<span class="token punctuation">.</span><span class="token function">abc</span><span class="token punctuation">(</span>text <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">?</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>MyXMLDocument.abc does something too... I just do not know what.</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.from_file" class="doc-node">
|
||||
<div class="title"><h2>fn MyXMLDocument.from_file <a href="#MyXMLDocument.from_file">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> MyXMLDocument<span class="token punctuation">.</span><span class="token function">from_file</span><span class="token punctuation">(</span>path <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">!</span>MyXMLDocument</code></pre>
|
||||
<p>MyXMLDocument.from_text processes the file path, and returns an error</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.from_text" class="doc-node">
|
||||
<div class="title"><h2>fn MyXMLDocument.from_text <a href="#MyXMLDocument.from_text">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> MyXMLDocument<span class="token punctuation">.</span><span class="token function">from_text</span><span class="token punctuation">(</span>text <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">?</span>MyXMLDocument</code></pre>
|
||||
<p>MyXMLDocument.from_text processes text and produces none</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument" class="doc-node">
|
||||
<div class="title"><h2>struct MyXMLDocument <a href="#MyXMLDocument">#</a></h2></div><pre class="signature"><code><span class="token keyword">struct</span> <span class="token symbol">MyXMLDocument</span> <span class="token punctuation">{</span>
|
||||
path <span class="token builtin">string</span>
|
||||
<span class="token punctuation">}</span></code></pre>
|
||||
<p>MyXMLDocument is here just to test the different combinations of methods/output types</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_from_file" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_from_file <a href="#MyXMLDocument.instance_from_file">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_from_file</span><span class="token punctuation">(</span>path <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">!</span>MyXMLDocument</code></pre>
|
||||
<p>instance_from_file does stuff with path</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_from_text" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_from_text <a href="#MyXMLDocument.instance_from_text">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_from_text</span><span class="token punctuation">(</span>text <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">?</span>MyXMLDocument</code></pre>
|
||||
<p>instance_from_text does stuff with text</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_abc" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_abc <a href="#MyXMLDocument.instance_abc">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_abc</span><span class="token punctuation">(</span>text <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">?</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>instance_abc does stuff too</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_void" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_void <a href="#MyXMLDocument.instance_void">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_void</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
|
||||
<p>instance_void does stuff too</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_int" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_int <a href="#MyXMLDocument.instance_int">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_int</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span></code></pre>
|
||||
<p>instance_int does stuff too</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_result" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_result <a href="#MyXMLDocument.instance_result">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_result</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!</span></code></pre>
|
||||
<p>instance_error does stuff too</p>
|
||||
|
||||
</section>
|
||||
<section id="MyXMLDocument.instance_option" class="doc-node">
|
||||
<div class="title"><h2>fn (MyXMLDocument) instance_option <a href="#MyXMLDocument.instance_option">#</a></h2></div><pre class="signature"><code><span class="token keyword">fn</span> <span class="token punctuation">(</span>x <span class="token operator">&</span>MyXMLDocument<span class="token punctuation">)</span> <span class="token function">instance_option</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">?</span></code></pre>
|
||||
<p>instance_option does stuff too</p>
|
||||
|
||||
</section>
|
35
cmd/tools/vdoc/tests/testdata/output_formats/main.text
vendored
Normal file
35
cmd/tools/vdoc/tests/testdata/output_formats/main.text
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
module main
|
||||
|
||||
const omega = 3 // should be first
|
||||
const alpha = 5 // should be in the middle
|
||||
const beta = 2 // should be at the end
|
||||
fn abc()
|
||||
abc - should be last
|
||||
fn def()
|
||||
def - should be first
|
||||
fn xyz()
|
||||
xyz - should be in the middle
|
||||
fn MyXMLDocument.abc(text string) ?(string, int)
|
||||
MyXMLDocument.abc does something too... I just do not know what.
|
||||
fn MyXMLDocument.from_file(path string) !MyXMLDocument
|
||||
MyXMLDocument.from_text processes the file path, and returns an error
|
||||
fn MyXMLDocument.from_text(text string) ?MyXMLDocument
|
||||
MyXMLDocument.from_text processes text and produces none
|
||||
struct MyXMLDocument {
|
||||
path string
|
||||
}
|
||||
MyXMLDocument is here just to test the different combinations of methods/output types
|
||||
fn (x &MyXMLDocument) instance_from_file(path string) !MyXMLDocument
|
||||
instance_from_file does stuff with path
|
||||
fn (x &MyXMLDocument) instance_from_text(text string) ?MyXMLDocument
|
||||
instance_from_text does stuff with text
|
||||
fn (x &MyXMLDocument) instance_abc(text string) ?(string, int)
|
||||
instance_abc does stuff too
|
||||
fn (x &MyXMLDocument) instance_void()
|
||||
instance_void does stuff too
|
||||
fn (x &MyXMLDocument) instance_int() int
|
||||
instance_int does stuff too
|
||||
fn (x &MyXMLDocument) instance_result() !
|
||||
instance_error does stuff too
|
||||
fn (x &MyXMLDocument) instance_option() ?
|
||||
instance_option does stuff too
|
75
cmd/tools/vdoc/tests/testdata/output_formats/main.v
vendored
Normal file
75
cmd/tools/vdoc/tests/testdata/output_formats/main.v
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
pub const omega = 3 // should be first
|
||||
|
||||
pub const alpha = 5 // should be in the middle
|
||||
|
||||
pub const beta = 2 // should be at the end
|
||||
|
||||
// def - should be first
|
||||
pub fn def() {
|
||||
println(1)
|
||||
}
|
||||
|
||||
// xyz - should be in the middle
|
||||
pub fn xyz() {
|
||||
println(2)
|
||||
}
|
||||
|
||||
// abc - should be last
|
||||
pub fn abc() {
|
||||
println(3)
|
||||
}
|
||||
|
||||
// MyXMLDocument is here just to test the different combinations of methods/output types
|
||||
pub struct MyXMLDocument {
|
||||
path string
|
||||
}
|
||||
|
||||
// MyXMLDocument.from_text processes the file path, and returns an error
|
||||
pub fn MyXMLDocument.from_file(path string) !MyXMLDocument {
|
||||
return error('TODO')
|
||||
}
|
||||
|
||||
// MyXMLDocument.from_text processes text and produces none
|
||||
pub fn MyXMLDocument.from_text(text string) ?MyXMLDocument {
|
||||
return none
|
||||
}
|
||||
|
||||
// MyXMLDocument.abc does something too... I just do not know what.
|
||||
pub fn MyXMLDocument.abc(text string) ?(string, int) {
|
||||
return 'xyz', 123
|
||||
}
|
||||
|
||||
// instance_from_file does stuff with path
|
||||
pub fn (x &MyXMLDocument) instance_from_file(path string) !MyXMLDocument {
|
||||
return error('TODO')
|
||||
}
|
||||
|
||||
// instance_from_text does stuff with text
|
||||
pub fn (x &MyXMLDocument) instance_from_text(text string) ?MyXMLDocument {
|
||||
return none
|
||||
}
|
||||
|
||||
// instance_abc does stuff too
|
||||
pub fn (x &MyXMLDocument) instance_abc(text string) ?(string, int) {
|
||||
return 'xyz', 123
|
||||
}
|
||||
|
||||
// instance_void does stuff too
|
||||
pub fn (x &MyXMLDocument) instance_void() {
|
||||
return 123
|
||||
}
|
||||
|
||||
// instance_int does stuff too
|
||||
pub fn (x &MyXMLDocument) instance_int() int {
|
||||
return 123
|
||||
}
|
||||
|
||||
// instance_error does stuff too
|
||||
pub fn (x &MyXMLDocument) instance_result() ! {
|
||||
return 123
|
||||
}
|
||||
|
||||
// instance_option does stuff too
|
||||
pub fn (x &MyXMLDocument) instance_option() ? {
|
||||
return 123
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
module foo
|
||||
|
||||
fn bar()
|
||||
fn bar()
|
||||
|
@ -1,4 +1,4 @@
|
||||
hello from readme
|
||||
module foo
|
||||
|
||||
fn bar()
|
||||
fn bar()
|
||||
|
@ -10,6 +10,8 @@ const vroot = @VMODROOT
|
||||
|
||||
const diff_cmd = find_diff_cmd()
|
||||
|
||||
const should_autofix = os.getenv('VAUTOFIX') != ''
|
||||
|
||||
fn find_diff_cmd() string {
|
||||
return diff.find_working_diff_command() or { '' }
|
||||
}
|
||||
@ -82,6 +84,23 @@ fn check_path(vexe string, dir string, tests []string) int {
|
||||
cmd: '${os.quoted_path(vexe)} doc -readme -comments ${os.quoted_path(program)}'
|
||||
out_filename: 'main.readme.comments.out'
|
||||
)
|
||||
// test the main 3 different formats:
|
||||
fails += check_output(
|
||||
program: program
|
||||
cmd: '${os.quoted_path(vexe)} doc -f html -o - -html-only-contents -readme -comments ${os.quoted_path(program)}'
|
||||
out_filename: 'main.html'
|
||||
)
|
||||
fails += check_output(
|
||||
program: program
|
||||
cmd: '${os.quoted_path(vexe)} doc -f ansi -o - -html-only-contents -readme -comments ${os.quoted_path(program)}'
|
||||
out_filename: 'main.ansi'
|
||||
)
|
||||
fails += check_output(
|
||||
program: program
|
||||
cmd: '${os.quoted_path(vexe)} doc -f text -o - -html-only-contents -readme -comments ${os.quoted_path(program)}'
|
||||
out_filename: 'main.text'
|
||||
)
|
||||
//
|
||||
total_fails += fails
|
||||
if fails == 0 {
|
||||
println(term.green('OK'))
|
||||
@ -141,9 +160,13 @@ fn check_output(params CheckOutputParams) int {
|
||||
found := clean_line_endings(res.output)
|
||||
if expected != found {
|
||||
print_compare(expected, found)
|
||||
eprintln('>>> out_file_path: ${out_file_path}')
|
||||
eprintln('>>> cmd: VDOC_SORT=${params.should_sort} ${params.cmd}')
|
||||
eprintln('>>> out_file_path: `${out_file_path}`')
|
||||
eprintln('>>> fix: VDOC_SORT=${params.should_sort} ${params.cmd} > ${out_file_path}')
|
||||
fails++
|
||||
}
|
||||
if should_autofix {
|
||||
os.write_file(out_file_path, res.output) or {}
|
||||
}
|
||||
return fails
|
||||
}
|
||||
|
@ -60,14 +60,14 @@ fn trim_doc_node_description(description string) string {
|
||||
}
|
||||
|
||||
fn set_output_type_from_str(format string) OutputType {
|
||||
output_type := match format {
|
||||
return match format {
|
||||
'htm', 'html' { OutputType.html }
|
||||
'md', 'markdown' { OutputType.markdown }
|
||||
'json' { OutputType.json }
|
||||
'stdout' { OutputType.stdout }
|
||||
else { OutputType.plaintext }
|
||||
'md', 'markdown' { .markdown }
|
||||
'json' { .json }
|
||||
'text' { .plaintext }
|
||||
'ansi' { .ansi }
|
||||
else { .ansi }
|
||||
}
|
||||
return output_type
|
||||
}
|
||||
|
||||
fn get_ignore_paths(path string) ![]string {
|
||||
@ -213,10 +213,13 @@ fn color_highlight(code string, tb &ast.Table) string {
|
||||
} else if
|
||||
(next_tok.kind in [.lcbr, .rpar, .eof, .comma, .pipe, .name, .rcbr, .assign, .key_pub, .key_mut, .pipe, .comma, .comment, .lt, .lsbr]
|
||||
&& next_tok.lit !in builtin)
|
||||
&& (prev.kind in [.name, .amp, .lcbr, .rsbr, .key_type, .assign, .dot, .question, .rpar, .key_struct, .key_enum, .pipe, .key_interface, .comment, .ellipsis]
|
||||
&& (prev.kind in [.name, .amp, .lcbr, .rsbr, .key_type, .assign, .dot, .not, .question, .rpar, .key_struct, .key_enum, .pipe, .key_interface, .comment, .ellipsis, .comma]
|
||||
&& prev.lit !in builtin) && ((tok.lit != '' && tok.lit[0].is_capital())
|
||||
|| prev_prev.lit in ['C', 'JS']) {
|
||||
tok_typ = .symbol
|
||||
} else if tok.lit[0].is_capital() && prev.kind == .lpar
|
||||
&& next_tok.kind == .comma {
|
||||
tok_typ = .symbol
|
||||
} else if next_tok.kind == .lpar
|
||||
|| (!(tok.lit != '' && tok.lit[0].is_capital())
|
||||
&& next_tok.kind in [.lt, .lsbr] && next_tok.pos == tok.pos + tok.lit.len) {
|
||||
|
@ -17,8 +17,8 @@ enum OutputType {
|
||||
html
|
||||
markdown
|
||||
json
|
||||
ansi // text with ANSI color escapes
|
||||
plaintext
|
||||
stdout
|
||||
}
|
||||
|
||||
@[heap]
|
||||
@ -36,28 +36,6 @@ mut:
|
||||
example_oks int // how many ok examples were found when `-run-examples` was passed, that compiled and finished with 0 exit code.
|
||||
}
|
||||
|
||||
struct Config {
|
||||
mut:
|
||||
pub_only bool = true
|
||||
show_loc bool // for plaintext
|
||||
is_color bool
|
||||
is_multi bool
|
||||
is_vlib bool
|
||||
is_verbose bool
|
||||
include_readme bool
|
||||
include_examples bool = true
|
||||
include_comments bool // for plaintext
|
||||
inline_assets bool
|
||||
theme_dir string = default_theme
|
||||
no_timestamp bool
|
||||
output_path string
|
||||
output_type OutputType = .unset
|
||||
input_path string
|
||||
symbol_name string
|
||||
platform doc.Platform
|
||||
run_examples bool // `-run-examples` will run all `// Example: assert mod.abc() == y` comments in the processed modules
|
||||
}
|
||||
|
||||
//
|
||||
struct Output {
|
||||
mut:
|
||||
@ -279,7 +257,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
||||
}
|
||||
if out.path.len == 0 {
|
||||
if cfg.output_type == .unset {
|
||||
out.typ = .stdout
|
||||
out.typ = .ansi
|
||||
} else {
|
||||
vd.vprintln('No output path has detected. Using input path instead.')
|
||||
out.path = cfg.input_path
|
||||
@ -289,7 +267,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
||||
ext := os.file_ext(out.path)
|
||||
out.typ = set_output_type_from_str(ext.all_after('.'))
|
||||
}
|
||||
if cfg.include_readme && out.typ !in [.html, .stdout] {
|
||||
if cfg.include_readme && out.typ !in [.html, .ansi, .plaintext] {
|
||||
eprintln('vdoc: Including README.md for doc generation is supported on HTML output, or when running directly in the terminal.')
|
||||
exit(1)
|
||||
}
|
||||
@ -312,7 +290,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
||||
comment := doc.DocComment{
|
||||
text: readme_contents
|
||||
}
|
||||
if out.typ == .stdout {
|
||||
if out.typ == .ansi {
|
||||
println(markdown.to_plain(readme_contents))
|
||||
} else if out.typ == .html && cfg.is_multi {
|
||||
vd.docs << doc.Doc{
|
||||
@ -365,7 +343,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
||||
exit(1)
|
||||
}
|
||||
vd.vprintln('Rendering docs...')
|
||||
if out.path.len == 0 || out.path == 'stdout' {
|
||||
if out.path.len == 0 || out.path == 'stdout' || out.path == '-' {
|
||||
if out.typ == .html {
|
||||
vd.render_static_html(out)
|
||||
}
|
||||
|
@ -11,22 +11,20 @@ Examples:
|
||||
v doc -m -f html vlib/
|
||||
|
||||
Generates the documentation of a given MODULE, DIRECTORY, or FILE
|
||||
and prints or saves them to its desired format. It can generate HTML, JSON,
|
||||
or Markdown format.
|
||||
and prints or saves them to its desired format: HTML, JSON,
|
||||
TEXT, ANSI or Markdown.
|
||||
|
||||
Options:
|
||||
-all Includes private and public functions/methods/structs/consts/enums.
|
||||
-color Forces the use of ANSI escape sequences to make the output colorful.
|
||||
-no-color Forces plain text output, without ANSI colors.
|
||||
Note: -color is on for -f ansi .
|
||||
-f Specifies the output format to be used.
|
||||
Available formats are:
|
||||
md/markdown, json, text, stdout and html/htm
|
||||
Available formats are: md/markdown, json, text, ansi and html/htm.
|
||||
-h, -help Prints this help text.
|
||||
-m Generate docs for modules listed in that folder.
|
||||
-o Specifies the output file/folder path where to store the
|
||||
generated docs.
|
||||
Set it to "stdout" to print the output instead of saving
|
||||
the contents to a file.
|
||||
-color Forces stdout colorize output.
|
||||
-no-color Forces plain text output, without ANSI colors.
|
||||
-o The output file/folder path where to store the docs. Use `-o stdout`
|
||||
or `-o -', to print the output instead of saving it to a file.
|
||||
-readme Include README.md to docs if present.
|
||||
-v Enables verbose logging. For debugging purposes.
|
||||
-no-timestamp Omits the timestamp in the output file.
|
||||
@ -36,7 +34,18 @@ For HTML mode:
|
||||
webpage directly.
|
||||
-theme-dir The directory for doc theme template
|
||||
|
||||
For plain text mode:
|
||||
The following options are useful for tests, that need stable output.
|
||||
They will omit generating text that is prone to changes, due to styling,
|
||||
but that otherwise do not affect the content.
|
||||
-html-only-contents Produce just the main content of the page,
|
||||
without theming, styling, CSS and JS tags etc.
|
||||
-html-no-vhash Omits the version hash.
|
||||
-html-no-assets Omits the CSS and JS asset tags.
|
||||
-html-no-right Omits the doc-toc right panel.
|
||||
-html-no-toc-urls Omits the toc_links panel
|
||||
-html-no-footer Omits the footer panel.
|
||||
|
||||
For the text and ansi modes:
|
||||
-l Shows the locations of the generated signatures.
|
||||
-comments Includes comments in the output.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user