vdoc: native syntax highlighting, system font, and intergrate normalize.css

pull/5231/head
Ned Palacios 2020-06-06 13:56:17 +08:00 committed by GitHub
parent c2fe4ffa85
commit c1ccd56119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 658 additions and 369 deletions

View File

@ -1,430 +1,625 @@
/*! 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;
--link-color: #2779bd;
--font-color: #000;
--ref-symbol-color: #dae1e7;
--ref-symbol-hover-color: #b8c2cc;
--title-bottom-line-color: #f1f5f8;
--code-signature-border-color: #a0aec0;
--menu-background-color: #4b6c88;
--menu-font-color: #fff;
--menu-indent-line-color: #ffffff66;
--menu-indent-line-active-color: #00000066;
--menu-scrollbar-color: #a0aec0;
--menu-toggle-icon-color: #fff;
--menu-toggle-icon-hover-color: #00000044;
--menu-search-background-color: #00000044;
--menu-search-font-color: #fff;
--toc-font-color: #2779bd;
--toc-indent-line-color: #dae1e7;
--background-color: #fff;
--timestamp-color: #b8c2cc;
--link-color: #2779bd;
--font-color: #000;
--ref-symbol-color: #dae1e7;
--ref-symbol-hover-color: #b8c2cc;
--title-bottom-line-color: #f1f5f8;
--code-signature-border-color: #a0aec0;
--menu-background-color: #4b6c88;
--menu-font-color: #fff;
--menu-indent-line-color: #ffffff66;
--menu-indent-line-active-color: #00000066;
--menu-scrollbar-color: #a0aec0;
--menu-toggle-icon-color: #fff;
--menu-toggle-icon-hover-color: #00000044;
--menu-search-background-color: #00000044;
--menu-search-font-color: #fff;
--toc-font-color: #2779bd;
--toc-indent-line-color: #dae1e7;
}
:root.dark .dark-icon {
display: none;
display: none;
}
:root:not(.dark) .light-icon {
display: none;
display: none;
}
body {
font-family: 'Inter', sans-serif;
background-color: #fff;
background-color: var(--background-color);
color: #000;
color: var(--font-color);
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;
--font-color: #fff;
--link-color: #90cdf4;
--ref-symbol-color: #2d3748;
--ref-symbol-hover-color: #4a5568;
--title-bottom-line-color: #2d3748;
--code-signature-border-color: #4a5568;
--menu-background-color: #2d3748;
--menu-font-color: #fff;
--menu-indent-line-color: #4a5568;
--menu-indent-line-active-color: #90cdf4;
--menu-scrollbar-color: #4a5568;
--menu-toggle-icon-color: #fff;
--menu-search-background-color: #4a5568;
--menu-search-font-color: #fff;
--toc-font-color: #90cdf4;
--toc-indent-line-color: #1a202c;
--background-color: #1a202c;
--timestamp-color: #b8c2cc;
--font-color: #fff;
--link-color: #90cdf4;
--ref-symbol-color: #2d3748;
--ref-symbol-hover-color: #4a5568;
--title-bottom-line-color: #2d3748;
--code-signature-border-color: #4a5568;
--menu-background-color: #2d3748;
--menu-font-color: #fff;
--menu-indent-line-color: #4a5568;
--menu-indent-line-active-color: #90cdf4;
--menu-scrollbar-color: #4a5568;
--menu-toggle-icon-color: #fff;
--menu-search-background-color: #4a5568;
--menu-search-font-color: #fff;
--toc-font-color: #90cdf4;
--toc-indent-line-color: #1a202c;
}
/** Reset for menus */
.doc-nav ul, .doc-toc ul {
list-style: none;
padding: 0;
margin: 0;
.doc-nav ul,
.doc-toc ul {
list-style: none;
padding: 0;
margin: 0;
}
.doc-nav {
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
display: flex;
background-color: #4b6c88;
background-color: var(--menu-background-color);
color: #fff;
color: var(--menu-font-color);
flex-direction: column;
overflow-y: auto;
height: 100vh;
z-index: 10;
scrollbar-width: thin;
scrollbar-color: #a0aec0 transparent;
scrollbar-color: var(--menu-scrollbar-color) transparent;
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 0;
display: flex;
background-color: #4b6c88;
background-color: var(--menu-background-color);
color: #fff;
color: var(--menu-font-color);
flex-direction: column;
overflow-y: auto;
height: 100vh;
z-index: 10;
scrollbar-width: thin;
scrollbar-color: #a0aec0 transparent;
scrollbar-color: var(--menu-scrollbar-color) transparent;
}
*::-webkit-scrollbar {
width: 8px;
width: 8px;
}
*::-webkit-scrollbar-track {
background: transparent;
background: transparent;
}
*::-webkit-scrollbar-thumb {
background-color: #a0aec0;
background-color: var(--menu-scrollbar-color);
border: 3px solid transparent;
background-color: #a0aec0;
background-color: var(--menu-scrollbar-color);
border: 3px solid transparent;
}
.doc-nav li {
line-height: 1.8;
font-weight: 300;
line-height: 1.8;
font-weight: 300;
}
.doc-nav .content.show {
display: flex;
display: flex;
}
.doc-nav .content.hidden {
display: none;
display: none;
}
.doc-nav #toggle-menu {
cursor: pointer;
padding: 0.3rem;
fill: #fff;
fill: var(--menu-toggle-icon-color);
cursor: pointer;
padding: 0.3rem;
fill: #fff;
fill: var(--menu-toggle-icon-color);
}
.doc-nav #toggle-menu:active {
background-color: #00000044;
background-color: var(--menu-toggle-icon-hover-color);
border-radius: 5rem;
background-color: #00000044;
background-color: var(--menu-toggle-icon-hover-color);
border-radius: 5rem;
}
.doc-nav > .heading-container {
position: relative; /* IE11 */
position: sticky;
position: -webkit-sticky;
top: 0;
background-color: #4b6c88;
background-color: var(--menu-background-color);
z-index: 10;
.doc-nav>.heading-container {
position: relative;
/* IE11 */
position: sticky;
position: -webkit-sticky;
top: 0;
background-color: #4b6c88;
background-color: var(--menu-background-color);
z-index: 10;
}
.doc-nav > .heading-container > .heading {
display: flex;
padding: 0 2rem;
height: 56px;
.doc-nav>.heading-container>.heading {
display: flex;
padding: 0 2rem;
height: 56px;
}
.doc-nav > .heading-container > .heading > .module {
font-size: 1.6rem;
font-weight: 500;
margin: 0;
.doc-nav>.heading-container>.heading>.module {
font-size: 1.6rem;
font-weight: 500;
margin: 0;
}
.doc-nav > .heading-container > .heading > .toggle-version-container {
display: flex;
align-items: center;
.doc-nav>.heading-container>.heading>.toggle-version-container {
display: flex;
align-items: center;
}
.doc-nav > .heading-container > .heading > .toggle-version-container > #dark-mode-toggle {
cursor: pointer;
fill: #fff;
display: flex;
visibility: hidden;
.doc-nav>.heading-container>.heading>.toggle-version-container>#dark-mode-toggle {
cursor: pointer;
fill: #fff;
display: flex;
visibility: hidden;
}
.doc-nav > .heading-container > .heading > .toggle-version-container > #dark-mode-toggle > svg {
width: 1.2rem;
height: 1.2rem;
.doc-nav>.heading-container>.heading>.toggle-version-container>#dark-mode-toggle>svg {
width: 1.2rem;
height: 1.2rem;
}
.doc-nav > .heading-container > .heading > #search {
margin-top: 1rem;
border: none;
border-radius: 0.2rem;
padding: 0.5rem 1rem;
outline: none;
background-color: #00000044;
background-color: var(--menu-search-background-color);
color: #fff;
color: var(--menu-search-font-color);
margin-left: -0.6rem;
margin-right: -0.6rem;
.doc-nav>.heading-container>.heading>#search {
margin-top: 1rem;
border: none;
border-radius: 0.2rem;
padding: 0.5rem 1rem;
outline: none;
background-color: #00000044;
background-color: var(--menu-search-background-color);
color: #fff;
color: var(--menu-search-font-color);
margin-left: -0.6rem;
margin-right: -0.6rem;
}
.doc-nav > .heading-container > .heading > #search::placeholder {
color: #edf2f7;
text-transform: uppercase;
font-size: 12px;
font-weight: 600;
.doc-nav>.heading-container>.heading>#search::placeholder {
color: #edf2f7;
text-transform: uppercase;
font-size: 12px;
font-weight: 600;
}
.doc-nav > .heading-container > .heading > #search:-ms-input-placeholder {
color: #edf2f7;
text-transform: uppercase;
font-size: 12px;
font-weight: 600;
.doc-nav>.heading-container>.heading>#search:-ms-input-placeholder {
color: #edf2f7;
text-transform: uppercase;
font-size: 12px;
font-weight: 600;
}
.doc-nav > .content {
padding: 0 2rem 2rem 2rem;
display: flex;
flex-direction: column;
.doc-nav>.content {
padding: 0 2rem 2rem 2rem;
display: flex;
flex-direction: column;
}
.doc-nav > .content > ul > li.active {
font-weight: 600;
.doc-nav>.content>ul>li.active {
font-weight: 600;
}
.doc-nav > .content > ul > li.open ul {
display: initial;
.doc-nav>.content>ul>li.open ul {
display: initial;
}
.doc-nav > .content > ul > li.open > .menu-row > .dropdown-arrow {
transform: initial;
.doc-nav>.content>ul>li.open>.menu-row>.dropdown-arrow {
transform: initial;
}
.doc-nav > .content > ul > li > .menu-row {
display: flex;
align-items: center;
.doc-nav>.content>ul>li>.menu-row {
display: flex;
align-items: center;
}
.doc-nav > .content > ul > li > .menu-row > .dropdown-arrow {
transform: rotate(-90deg);
height: 18px;
width: 18px;
margin-left: calc(-18px - 0.3rem);
margin-right: 0.3rem;
cursor: pointer;
fill: #fff;
pointer-events: all;
.doc-nav>.content>ul>li>.menu-row>.dropdown-arrow {
transform: rotate(-90deg);
height: 18px;
width: 18px;
margin-left: calc(-18px - 0.3rem);
margin-right: 0.3rem;
cursor: pointer;
fill: #fff;
pointer-events: all;
}
.doc-nav > .content > ul > li > ul {
margin: 0.4rem 0;
display: none;
.doc-nav>.content>ul>li>ul {
margin: 0.4rem 0;
display: none;
}
.doc-nav > .content > ul > li > ul > li {
border-color: #ffffff66;
border-color: var(--menu-indent-line-color);
border-left-width: 1.7px;
border-left-style: solid;
padding-left: 0.7rem;
.doc-nav>.content>ul>li>ul>li {
border-color: #ffffff66;
border-color: var(--menu-indent-line-color);
border-left-width: 1.7px;
border-left-style: solid;
padding-left: 0.7rem;
}
.doc-nav > .content > ul > li > ul > li.active {
border-color: #00000066;
border-color: var(--menu-indent-line-active-color);
.doc-nav>.content>ul>li>ul>li.active {
border-color: #00000066;
border-color: var(--menu-indent-line-active-color);
}
.doc-nav > .content a {
color: #fff;
color: var(--menu-font-color);
text-decoration: none;
user-select: none;
.doc-nav>.content a {
color: #fff;
color: var(--menu-font-color);
text-decoration: none;
user-select: none;
}
.doc-nav > .content a:hover {
text-decoration: underline;
.doc-nav>.content a:hover {
text-decoration: underline;
}
.doc-container {
display: flex;
flex-direction: column-reverse;
margin-top: 56px;
display: flex;
flex-direction: column-reverse;
margin-top: 56px;
}
.doc-content {
padding: 1rem 2rem;
overflow: hidden;
padding: 1rem 2rem;
overflow: hidden;
}
.doc-content a {
color: var(--link-color);
color: var(--link-color);
}
.doc-content > .doc-node:not(:last-child) {
padding: 1rem 0 3rem 0;
.doc-content>.doc-node:not(:last-child) {
padding: 1rem 0 3rem 0;
}
.doc-content > .timestamp {
font-size: 0.8rem;
color: #b8c2cc;
color: var(--timestamp-color);
.doc-content>.timestamp {
font-size: 0.8rem;
color: #b8c2cc;
color: var(--timestamp-color);
}
.doc-content > .doc-node > .title {
display: flex;
align-items: center;
margin-bottom: 1rem;
border-bottom: 1px solid #f1f5f8;
border-bottom: 1px solid var(--title-bottom-line-color);
.doc-content>.doc-node>.title {
display: flex;
align-items: center;
margin-bottom: 1rem;
border-bottom: 1px solid #f1f5f8;
border-bottom: 1px solid var(--title-bottom-line-color);
}
.doc-content > .doc-node > .title > .link {
margin-left: auto;
fill: #dae1e7;
fill: var(--ref-symbol-color);
.doc-content>.doc-node>.title>.link {
margin-left: auto;
fill: #dae1e7;
fill: var(--ref-symbol-color);
}
.doc-content > .doc-node > .title > .link:hover {
fill: var(--ref-symbol-hover-color);
.doc-content>.doc-node>.title>.link:hover {
fill: var(--ref-symbol-hover-color);
}
.doc-content > .doc-node h1 {
font-size: 2.5rem;
font-weight: 400;
.doc-content>.doc-node h1 {
font-size: 2.5rem;
font-weight: 400;
}
.doc-content > .doc-node .signature {
border-color: #a0aec0;
border-color: var(--code-signature-border-color);
border-left-width: 3px;
border-left-style: solid;
.doc-content>.doc-node .signature {
border-color: #a0aec0;
border-color: var(--code-signature-border-color);
border-left-width: 3px;
border-left-style: solid;
}
.doc-content > .doc-node > ul > li .task-list-item-checkbox {
margin-right: 0.5rem;
.doc-content>.doc-node>ul>li .task-list-item-checkbox {
margin-right: 0.5rem;
}
.doc-content > .doc-node > .title h1,
.doc-content > .doc-node > .title h2,
.doc-content > .doc-node > .title h3,
.doc-content > .doc-node > .title h4,
.doc-content > .doc-node > .title h5,
.doc-content > .doc-node > .title h6 {
font-weight: 400;
padding-bottom: 0.8rem;
margin: 0;
.doc-content>.doc-node>.title h1,
.doc-content>.doc-node>.title h2,
.doc-content>.doc-node>.title h3,
.doc-content>.doc-node>.title h4,
.doc-content>.doc-node>.title h5,
.doc-content>.doc-node>.title h6 {
font-weight: 400;
padding-bottom: 0.8rem;
margin: 0;
}
.doc-content > .doc-node > .title h1 a,
.doc-content > .doc-node > .title h2 a,
.doc-content > .doc-node > .title h3 a,
.doc-content > .doc-node > .title h4 a,
.doc-content > .doc-node > .title h5 a,
.doc-content > .doc-node > .title h6 a {
text-decoration: none;
color: #dae1e7;
color: var(--ref-symbol-color);
.doc-content>.doc-node>.title h1 a,
.doc-content>.doc-node>.title h2 a,
.doc-content>.doc-node>.title h3 a,
.doc-content>.doc-node>.title h4 a,
.doc-content>.doc-node>.title h5 a,
.doc-content>.doc-node>.title h6 a {
text-decoration: none;
color: #dae1e7;
color: var(--ref-symbol-color);
}
.doc-content > .doc-node > .title h1 a:hover,
.doc-content > .doc-node > .title h2 a:hover,
.doc-content > .doc-node > .title h3 a:hover,
.doc-content > .doc-node > .title h4 a:hover,
.doc-content > .doc-node > .title h5 a:hover,
.doc-content > .doc-node > .title h6 a:hover {
color: var(--ref-symbol-hover-color);
.doc-content>.doc-node>.title h1 a:hover,
.doc-content>.doc-node>.title h2 a:hover,
.doc-content>.doc-node>.title h3 a:hover,
.doc-content>.doc-node>.title h4 a:hover,
.doc-content>.doc-node>.title h5 a:hover,
.doc-content>.doc-node>.title h6 a:hover {
color: var(--ref-symbol-hover-color);
}
.doc-toc {
right: 0;
top: 0;
height: 100%;
overflow-y: auto;
padding: 2rem;
width: 100%;
box-sizing: border-box;
-ms-overflow-style: none;
scrollbar-width: none;
right: 0;
top: 0;
height: 100%;
overflow-y: auto;
padding: 2rem;
width: 100%;
box-sizing: border-box;
-ms-overflow-style: none;
scrollbar-width: none;
}
.doc-toc::-webkit-scrollbar {
display: none;
display: none;
}
.doc-toc li {
line-height: 1.5;
line-height: 1.5;
}
.doc-toc a {
color: #2779bd;
color: var(--toc-font-color);
font-size: 0.9rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
display: block;
text-decoration: none;
color: #2779bd;
color: var(--toc-font-color);
font-size: 0.9rem;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
display: block;
text-decoration: none;
}
.doc-toc a:hover {
text-decoration: underline;
text-decoration: underline;
}
.doc-toc li ul {
border-color :#dae1e7;
border-color: var(--toc-indent-line-color);
border-left-width: 2px;
border-left-style: solid;
padding-left: 0.8rem;
margin: 0.2rem 0 0.2rem;
font-size: 0.7rem;
list-style: none;
border-color: #dae1e7;
border-color: var(--toc-indent-line-color);
border-left-width: 2px;
border-left-style: solid;
padding-left: 0.8rem;
margin: 0.2rem 0 0.2rem;
font-size: 0.7rem;
list-style: none;
}
.doc-toc li ul a {
font-weight: 400;
font-weight: 400;
}
/* Medium screen and up */
@media (min-width: 768px) {
.doc-container {
flex-direction: row;
}
.doc-content {
flex: 1;
}
.doc-toc {
padding: 1rem 1rem 0 1rem;
position: relative; /* IE11 */
position: sticky;
position: -webkit-sticky;
align-self: flex-start;
top: 56px;
height: auto;
height: 100vh;
min-width: 200px;
width: auto;
max-width: 300px;
}
.doc-toc > ul {
padding-bottom: 1rem;
}
.doc-container {
flex-direction: row;
}
.doc-content {
flex: 1;
}
.doc-toc {
padding: 1rem 1rem 0 1rem;
position: relative;
/* IE11 */
position: sticky;
position: -webkit-sticky;
align-self: flex-start;
top: 56px;
height: auto;
height: 100vh;
min-width: 200px;
width: auto;
max-width: 300px;
}
.doc-toc>ul {
padding-bottom: 1rem;
}
}
@media (max-width: 1023px) {
.doc-nav.hidden {
height: auto;
}
.doc-nav > .heading-container > .heading {
align-items: center;
}
.doc-nav > .heading-container > .heading > .toggle-version-container {
flex-grow: 1;
padding: 0 1rem;
justify-content: space-between;
}
.doc-nav > .heading-container > .heading > #search {
display: none;
}
.doc-nav.hidden {
height: auto;
}
.doc-nav>.heading-container>.heading {
align-items: center;
}
.doc-nav>.heading-container>.heading>.toggle-version-container {
flex-grow: 1;
padding: 0 1rem;
justify-content: space-between;
}
.doc-nav>.heading-container>.heading>#search {
display: none;
}
}
@media (min-width: 1024px) {
.doc-nav {
width: 300px;
}
.doc-nav #toggle-menu {
display: none;
}
.doc-nav > .heading-container > .heading {
height: auto;
padding-top: 1rem;
padding-bottom: 1rem;
flex-direction: column-reverse;
justify-content: center;
}
.doc-nav > .heading-container > .heading > .toggle-version-container {
align-items: center;
margin-bottom: 0.2rem;
display: flex;
flex-direction: row-reverse;
}
.doc-nav > .heading-container > .heading > .toggle-version-container > #dark-mode-toggle {
margin-right: auto;
}
.doc-nav .content.show,
.doc-nav .content.hidden {
display: flex;
}
.doc-container {
margin-top: 0;
margin-left: 300px;
}
.doc-toc {
top: 0;
}
}
.doc-nav {
width: 300px;
}
.doc-nav #toggle-menu {
display: none;
}
.doc-nav>.heading-container>.heading {
height: auto;
padding-top: 1rem;
padding-bottom: 1rem;
flex-direction: column-reverse;
justify-content: center;
}
.doc-nav>.heading-container>.heading>.toggle-version-container {
align-items: center;
margin-bottom: 0.2rem;
display: flex;
flex-direction: row-reverse;
}
.doc-nav>.heading-container>.heading>.toggle-version-container>#dark-mode-toggle {
margin-right: auto;
}
.doc-nav .content.show,
.doc-nav .content.hidden {
display: flex;
}
.doc-container {
margin-top: 0;
margin-left: 300px;
}
.doc-toc {
top: 0;
}
}

View File

@ -7,8 +7,43 @@ import os
import os.cmdline
import strings
import v.doc
import v.scanner
import v.table
import v.token
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 (
allowed_formats = ['md', 'markdown', 'json', 'text', 'stdout', 'html', 'htm']
exe_path = os.executable()
@ -131,32 +166,98 @@ fn (cfg DocConfig) gen_json(idx int) string {
return jw.str()
}
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 }
return if typ in [.unone, .name] { lit } else { '<span class="token $typ">$lit</span>' }
}
s := scanner.new_scanner(code, .parse_comments)
mut tok := s.scan()
mut next_tok := s.scan()
mut buf := strings.new_builder(200)
mut i := 0
for i < code.len {
if i == tok.pos {
mut tok_typ := HighlightTokenTyp.unone
match tok.kind {
.name {
if tok.lit in builtin {
tok_typ = .builtin
} else if next_tok.kind in [.lcbr, .lpar] {
tok_typ = .symbol
} else {
tok_typ = .name
}
}
.comment {
tok_typ = .comment
}
.chartoken {
tok_typ = .char
}
.string {
tok_typ = .string
}
.number {
tok_typ = .number
}
.key_true,
.key_false {
tok_typ = .boolean
}
else {
if token.is_key(tok.lit) || token.is_decl(tok.kind) {
tok_typ = .keyword
} else if tok.kind == .decl_assign || tok.kind.is_assign() || tok.is_unary() || tok.kind.is_relational() || tok.kind.is_infix() {
tok_typ = .operator
}
}
}
buf.write(highlight_code(tok, tok_typ))
if next_tok.kind != .eof {
i = tok.pos + tok.len
tok = next_tok
next_tok = s.scan()
} else {
break
}
} else {
buf.write_b(code[i])
i++
}
}
return buf.str()
}
fn doc_node_html(dd doc.DocNode, link string, head bool, tb &table.Table) string {
mut dnw := strings.new_builder(200)
link_svg := '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'
head_tag := if head { 'h1' } else { 'h2' }
md_content := markdown.to_html(dd.comment)
hlighted_code := html_highlight(dd.content, tb)
dnw.writeln('<section id="${slug(dd.name)}" class="doc-node">')
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('</div>')
}
if head {
dnw.write(md_content)
} else {
dnw.writeln('<pre class="signature language-v"><code class="language-v">$hlighted_code</code></pre>')
dnw.writeln(md_content)
}
dnw.writeln('</section>')
return dnw.str()
}
fn (cfg DocConfig) gen_html(idx int) string {
dcs := cfg.docs[idx]
mut hw := strings.new_builder(200)
mut toc := strings.new_builder(200)
mut doc_node_html := fn (dd doc.DocNode, link string, head bool) string {
mut dnw := strings.new_builder(200)
link_svg := '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'
head_tag := if head { 'h1' } else { 'h2' }
md_content := markdown.to_html(dd.comment)
dnw.writeln('<section id="${slug(dd.name)}" class="doc-node">')
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('</div>')
}
if head {
dnw.write(md_content)
} else {
dnw.writeln('<pre class="signature"><code class="language-v">${dd.content}</code></pre>')
dnw.writeln(md_content)
}
dnw.writeln('</section>')
return dnw.str()
}
// generate toc first
for cn in dcs.contents {
if cn.parent_type !in ['void', ''] { continue }
@ -179,7 +280,6 @@ fn (cfg DocConfig) gen_html(idx int) string {
dark_icon := cfg.get_resource('dark.svg', true)
menu_icon := cfg.get_resource('menu.svg', true)
arrow_icon := cfg.get_resource('arrow.svg', true)
v_prism_js := cfg.get_resource('v-prism.js', false)
v_prism_css := cfg.get_resource('v-prism.css', true)
hw.write('
@ -189,16 +289,14 @@ fn (cfg DocConfig) gen_html(idx int) string {
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${dcs.head.name} | vdoc</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Source+Code+Pro:wght@500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.1/normalize.css" />')
<title>${dcs.head.name} | vdoc</title>')
// write css
if cfg.inline_assets {
hw.write('<style>$v_prism_css</style>')
hw.write('<style>$doc_css_min</style>')
hw.write('\n <style>$v_prism_css</style>')
hw.write('\n <style>$doc_css_min</style>')
} else {
hw.write('\n <link rel="stylesheet" href="$v_prism_css" />')
hw.write('\n <link rel="stylesheet" href="$v_prism_css" />')
hw.write('\n <link rel="stylesheet" href="$doc_css_min" />')
}
@ -266,19 +364,19 @@ fn (cfg DocConfig) gen_html(idx int) string {
}
hw.write('</ul>\n</nav>\n</header>')
hw.write('<div class="doc-container">\n<div class="doc-content">\n')
hw.write(doc_node_html(dcs.head, '', true))
hw.write(doc_node_html(dcs.head, '', true, dcs.table))
for cn in dcs.contents {
if cn.parent_type !in ['void', ''] { continue }
base_dir := os.base_dir(os.real_path(cfg.input_path))
file_path_name := cn.file_path.replace('$base_dir/', '')
hw.write(doc_node_html(cn, get_src_link(cfg.manifest.repo_url, file_path_name, cn.pos.line), false))
hw.write(doc_node_html(cn, get_src_link(cfg.manifest.repo_url, file_path_name, cn.pos.line), false, dcs.table))
children := dcs.contents.find_children_of(cn.name)
if children.len != 0 {
for child in children {
child_file_path_name := child.file_path.replace('$base_dir/', '')
hw.write(doc_node_html(child, get_src_link(cfg.manifest.repo_url, child_file_path_name, child.pos.line), false))
hw.write(doc_node_html(child, get_src_link(cfg.manifest.repo_url, child_file_path_name, child.pos.line), false, dcs.table))
}
}
}
@ -287,14 +385,10 @@ fn (cfg DocConfig) gen_html(idx int) string {
hw.write('<div class="doc-toc">\n\n<ul>\n${toc.str()}</ul>\n</div>')
}
hw.write('</div></div>')
hw.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/components/prism-clike.min.js"></script>')
if cfg.inline_assets {
hw.write('<script>$doc_js_min</script>')
hw.write('<script>$v_prism_js</script>')
} else {
hw.write('<script src="$doc_js_min"></script>')
hw.write('<script src="$v_prism_js"></script>')
}
hw.write('</body>
</html>')