vdoc: add footer, improve accessibility and highlighting
parent
7815c5b108
commit
a19aaf2b90
|
@ -1,147 +1,3 @@
|
|||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
html {
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
legend {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
:root {
|
||||
--background-color: #fff;
|
||||
--timestamp-color: #b8c2cc;
|
||||
|
@ -150,10 +6,12 @@ template {
|
|||
--ref-symbol-color: #dae1e7;
|
||||
--ref-symbol-hover-color: #b8c2cc;
|
||||
--title-bottom-line-color: #f1f5f8;
|
||||
--footer-top-line-color: #f1f5f8;
|
||||
--footer-font-color: #616161;
|
||||
--code-signature-border-color: #a0aec0;
|
||||
--menu-background-color: #4b6c88;
|
||||
--menu-font-color: #fff;
|
||||
--menu-indent-line-color: #ffffff66;
|
||||
--menu-indent-line-color: #3b3b3b66;
|
||||
--menu-indent-line-active-color: #00000066;
|
||||
--menu-scrollbar-color: #a0aec0;
|
||||
--menu-toggle-icon-color: #fff;
|
||||
|
@ -172,14 +30,6 @@ template {
|
|||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
background-color: #fff;
|
||||
background-color: var(--background-color);
|
||||
color: #000;
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
.dark body {
|
||||
--background-color: #1a202c;
|
||||
--timestamp-color: #b8c2cc;
|
||||
|
@ -188,6 +38,8 @@ body {
|
|||
--ref-symbol-color: #2d3748;
|
||||
--ref-symbol-hover-color: #4a5568;
|
||||
--title-bottom-line-color: #2d3748;
|
||||
--footer-top-line-color: #2d3748;
|
||||
--footer-font-color: #bbd3e1;
|
||||
--code-signature-border-color: #4a5568;
|
||||
--menu-background-color: #2d3748;
|
||||
--menu-font-color: #fff;
|
||||
|
@ -201,9 +53,189 @@ body {
|
|||
--toc-indent-line-color: #1a202c;
|
||||
}
|
||||
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
html {
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
background-color: #fff;
|
||||
background-color: var(--background-color);
|
||||
color: #000;
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
legend {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** Reset for menus */
|
||||
|
||||
.doc-nav ul,
|
||||
.doc-toc ul {
|
||||
list-style: none;
|
||||
|
@ -409,6 +441,8 @@ body {
|
|||
}
|
||||
|
||||
.doc-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem 2rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -492,6 +526,14 @@ body {
|
|||
color: var(--ref-symbol-hover-color);
|
||||
}
|
||||
|
||||
.doc-content .footer {
|
||||
padding-top: 1rem;
|
||||
margin-top: auto;
|
||||
bottom: 1rem;
|
||||
color: var(--footer-font-color);
|
||||
border-top: 1px solid var(--footer-top-line-color);
|
||||
}
|
||||
|
||||
.doc-toc {
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
(function() {
|
||||
if (!!document.body.scrollIntoView) {
|
||||
var docnav = document.querySelector('.doc-nav');
|
||||
var active = docnav.querySelector('li.active');
|
||||
active && active.scrollIntoView({ block: 'center', inline: 'nearest' });
|
||||
}
|
||||
|
||||
// Mobile view menu toggle button
|
||||
var toggle = document.getElementById("toggle-menu");
|
||||
toggle.addEventListener("click", function(ev) {
|
||||
document.querySelectorAll(".doc-nav").forEach(function(el) {
|
||||
el.classList.toggle("hidden");
|
||||
var toggle = document.getElementById('toggle-menu');
|
||||
toggle.addEventListener('click', function(ev) {
|
||||
document.querySelectorAll('.doc-nav').forEach(function(el) {
|
||||
el.classList.toggle('hidden');
|
||||
});
|
||||
document.querySelectorAll(".doc-nav .content").forEach(function(el) {
|
||||
el.classList.toggle("hidden");
|
||||
el.classList.toggle("show");
|
||||
document.querySelectorAll('.doc-nav .content').forEach(function(el) {
|
||||
el.classList.toggle('hidden');
|
||||
el.classList.toggle('show');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -18,6 +24,7 @@
|
|||
html.classList.toggle('dark');
|
||||
var isDarkModeEnabled = html.classList.contains('dark');
|
||||
localStorage.setItem('dark-mode', isDarkModeEnabled);
|
||||
darkModeToggle.setAttribute('aria-checked', isDarkModeEnabled)
|
||||
});
|
||||
if (localStorage.getItem('dark-mode') === 'true') {
|
||||
html.classList.add('dark');
|
||||
|
@ -63,4 +70,4 @@
|
|||
parent.classList.toggle('open');
|
||||
});
|
||||
}
|
||||
})();
|
||||
})();
|
|
@ -61,10 +61,7 @@ pre[class*="language-"] {
|
|||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
.token.comment {
|
||||
color: #93a1a1;
|
||||
color: var(--code-comment-text-color)
|
||||
}
|
||||
|
@ -72,21 +69,14 @@ pre[class*="language-"] {
|
|||
color: #999999;
|
||||
color: var(--code-punctuation-text-color);
|
||||
}
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
.token.symbol {
|
||||
color: #702459;
|
||||
color: var(--code-symbol-text-color);
|
||||
}
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
.token.builtin {
|
||||
color: #38a169;
|
||||
color: var(--code-builtin-text-color);
|
||||
}
|
||||
|
@ -100,8 +90,6 @@ pre[class*="language-"] {
|
|||
background: transparent;
|
||||
}
|
||||
.token.boolean,
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #2b6cb0;
|
||||
color: var(--code-keyword-text-color);
|
||||
|
@ -110,13 +98,3 @@ pre[class*="language-"] {
|
|||
color: #319795;
|
||||
color: var(--code-function-text-color);
|
||||
}
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
(function() {
|
||||
Prism.languages.v = Prism.languages.extend('clike', {
|
||||
keyword: /\b(?:pub|break|const|continue|defer|else|for|fn|go(?:to)?|if|import|module|return|interface|struct|match|type|mut|is|as|map|__global|enum)\b/,
|
||||
builtin: /\b(?:bool|string|i8|i16|int|i64|i128|byte|u16|u32|u64|u128|rune|f32|f64|any_int|any_float|byteptr|voidptr|any)\b/,
|
||||
boolean: /\b(?:_|true|false)\b/,
|
||||
operator: /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
|
||||
number: /(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
|
||||
string: {
|
||||
pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
|
||||
greedy: true,
|
||||
},
|
||||
});
|
||||
delete Prism.languages.v['class-name'];
|
||||
})();
|
|
@ -14,34 +14,18 @@ import v.vmod
|
|||
|
||||
enum HighlightTokenTyp {
|
||||
unone
|
||||
atrule
|
||||
attr_name
|
||||
bold
|
||||
boolean
|
||||
builtin
|
||||
char
|
||||
comment
|
||||
constant
|
||||
cdata
|
||||
deleted
|
||||
doctype
|
||||
entity
|
||||
function
|
||||
important
|
||||
inserted
|
||||
italic
|
||||
keyword
|
||||
name
|
||||
number
|
||||
operator
|
||||
prolog
|
||||
property
|
||||
punctuation
|
||||
selector
|
||||
string
|
||||
symbol
|
||||
tag
|
||||
url
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -169,7 +153,7 @@ fn (cfg DocConfig) gen_json(idx int) string {
|
|||
fn html_highlight(code string, tb &table.Table) string {
|
||||
builtin := ['bool', 'string', 'i8', 'i16', 'int', 'i64', 'i128', 'byte', 'u16', 'u32', 'u64', 'u128', 'rune', 'f32', 'f64', 'any_int', 'any_float', 'byteptr', 'voidptr', 'any']
|
||||
highlight_code := fn (tok token.Token, typ HighlightTokenTyp) string {
|
||||
lit := if typ in [.unone, .operator] { tok.kind.str() } else { tok.lit }
|
||||
lit := if typ in [.unone, .operator, .punctuation] { tok.kind.str() } else { tok.lit }
|
||||
return if typ in [.unone, .name] { lit } else { '<span class="token $typ">$lit</span>' }
|
||||
}
|
||||
s := scanner.new_scanner(code, .parse_comments)
|
||||
|
@ -202,10 +186,13 @@ fn html_highlight(code string, tb &table.Table) string {
|
|||
.number {
|
||||
tok_typ = .number
|
||||
}
|
||||
.key_true,
|
||||
.key_false {
|
||||
.key_true, .key_false {
|
||||
tok_typ = .boolean
|
||||
}
|
||||
.lpar, .lcbr, .rpar, .rcbr, .lsbr,
|
||||
.rsbr, .semicolon, .colon, .comma, .dot {
|
||||
tok_typ = .punctuation
|
||||
}
|
||||
else {
|
||||
if token.is_key(tok.lit) || token.is_decl(tok.kind) {
|
||||
tok_typ = .keyword
|
||||
|
@ -240,7 +227,7 @@ fn doc_node_html(dd doc.DocNode, link string, head bool, tb &table.Table) string
|
|||
if dd.name != 'README' {
|
||||
dnw.write('<div class="title"><$head_tag>${dd.name} <a href="#${slug(dd.name)}">#</a></$head_tag>')
|
||||
if link.len != 0 {
|
||||
dnw.write('<a class="link" target="_blank" href="$link">$link_svg</a>')
|
||||
dnw.write('<a class="link" rel="noreferrer" target="_blank" href="$link">$link_svg</a>')
|
||||
}
|
||||
dnw.write('</div>')
|
||||
}
|
||||
|
@ -256,6 +243,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()
|
||||
mut hw := strings.new_builder(200)
|
||||
mut toc := strings.new_builder(200)
|
||||
// generate toc first
|
||||
|
@ -313,7 +301,7 @@ fn (cfg DocConfig) gen_html(idx int) string {
|
|||
<div class="module">${header_name}</div>
|
||||
<div class="toggle-version-container">
|
||||
<span>${version}</span>
|
||||
<div id="dark-mode-toggle" role="checkbox">$light_icon $dark_icon</div>
|
||||
<div id="dark-mode-toggle" role="switch" aria-checked="false" aria-label="Toggle dark mode">$light_icon $dark_icon</div>
|
||||
</div>
|
||||
$menu_icon
|
||||
</div>
|
||||
|
@ -380,7 +368,7 @@ fn (cfg DocConfig) gen_html(idx int) string {
|
|||
}
|
||||
}
|
||||
}
|
||||
hw.write('\n</div>\n')
|
||||
hw.write('\n<div class="footer">Powered by vdoc. Generated on: $time_gen</div>\n</div>\n')
|
||||
if cfg.is_multi && cfg.docs.len > 1 && dcs.head.name != 'README' {
|
||||
hw.write('<div class="doc-toc">\n\n<ul>\n${toc.str()}</ul>\n</div>')
|
||||
}
|
||||
|
@ -537,10 +525,9 @@ fn (mut cfg DocConfig) generate_docs_from_file() {
|
|||
panic(err)
|
||||
}
|
||||
} else {
|
||||
os.rm(os.join_path(cfg.output_path, 'doc.css'))
|
||||
os.rm(os.join_path(cfg.output_path, 'v-prism.css'))
|
||||
os.rm(os.join_path(cfg.output_path, 'v-prism.js'))
|
||||
os.rm(os.join_path(cfg.output_path, 'doc.js'))
|
||||
for fname in ['doc.css', 'v-prism.css', 'doc.js'] {
|
||||
os.rm(os.join_path(cfg.output_path, fname))
|
||||
}
|
||||
}
|
||||
}
|
||||
outputs := cfg.render()
|
||||
|
|
Loading…
Reference in New Issue