Improve rendering to match the main website's CSS

This commit is contained in:
gingerBill
2022-01-19 13:20:38 +00:00
parent 841c428273
commit db08847f9a
4 changed files with 241 additions and 151 deletions

View File

@@ -0,0 +1,43 @@
</div>
</main>
<footer class="odin-footer">
<div class="container pb-5 pt-5">
<div class="row g-4">
<div class="col">
<a class="navbar-brand" href="//odin-lang.org">
<img class="mb-3" src="//odin-lang.org/logo.svg" height="30" alt="Odin"></a>
<p>
The Data-Oriented Language for Sane Software Development.
</p>
</div>
<nav class="col-md-auto">
<h4 class="fw-normal">Resources</h4>
<ul class="list-unstyled">
<li><a href="//odin-lang.org/docs" class="link-light">Docs</a></li>
<li><a href="//odin-lang.org/news" class="link-light">Blog</a></li>
</ul>
</nav>
<nav class="col-md-auto">
<h4 class="fw-normal">Community</h4>
<ul class="list-unstyled">
<li><a href="https://github.com/odin-lang/Odin" target="_blank" class="link-light">GitHub</a></li>
<li><a href="https://discord.com/invite/sVBPHEv" target="_blank" class="link-light">Discord</a></li>
<li><a href="https://www.twitch.tv/ginger_bill" target="_blank" class="link-light">Twitch</a></li>
<li><a href="https://www.youtube.com/channel/UCUSck1dOH7VKmG4lRW7tZXg" target="_blank" class="link-light">YouTube</a></li>
</ul>
</nav>
<nav class="col-md-auto">
<h4 class="fw-normal">Contribute</h4>
<ul class="list-unstyled">
<li><a href="https://github.com/odin-lang/Odin/issues" target="_blank" class="link-light">Issues</a></li>
<li><a href="https://www.patreon.com/gingerbill" target="_blank" class="link-light">Donate</a></li>
</ul>
</nav>
</div>
<div class="mt-4 text-muted">© 20162022 Ginger Bill</div>
</div>
</footer>
<script src="//odin-lang.org/lib/bootstrap/js/bootstrap.min.js"></script>
<script src="//odin-lang.org/js/script.js"></script>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{0:s}</title>
<script type="text/javascript" src="https://livejs.com/live.js"></script>
<link rel="stylesheet" type="text/css" href="https://odin-lang.org/scss/custom.min.css">
<link rel="stylesheet" type="text/css" href="https://odin-lang.org/css/style.css">
<link rel="stylesheet" type="text/css" href="/style.css">
</style>
</head>
<body>
<header class="sticky-top">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary odin-menu">
<div class="container">
<a class="navbar-brand" href="/core">
<img src="//odin-lang.org/logo.svg" height="30" alt="Odin"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#odin-navbar-content" aria-controls="odin-navbar-content" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="odin-navbar-content">
<ul class="navbar-nav ms-md-auto">
<li class="nav-item"><a class="nav-link" href="/core">Home</a></li>
<li class="nav-item"><a class="nav-link active" href="//odin-lang.org" aria-current="page">Language</a></li>
<li class="nav-item"><a class="nav-link" href="https://github.com/odin-lang/Odin" target="_blank">GitHub</a></li>
</ul>
</div>
</div>
</nav>
</header>
<main>
<div class="container">

View File

@@ -88,71 +88,62 @@ recursive_make_directory :: proc(path: string, prefix := "") {
write_html_header :: proc(w: io.Writer, title: string) {
fmt.wprintf(w, `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>%s</title>
<script type="text/javascript" src="https://livejs.com/live.js"></script>
<link rel="stylesheet" type="text/css" href="/style.css">
</style>
</head>
<body>`, title)
fmt.wprintln(w, "\n<div class=\"container\">")
fmt.wprintln(w, "\n<a href=\"/core\">Core Directory</a>")
fmt.wprintf(w, string(#load("header.txt.html")), title)
}
write_html_footer :: proc(w: io.Writer) {
io.write_string(w, `
<script type="text/javascript">
(function (win, doc) {
'use strict';
if (!doc.querySelectorAll || !win.addEventListener) {
// doesn't cut the mustard.
return;
write_html_footer :: proc(w: io.Writer, include_directory_js: bool) {
fmt.wprintf(w, "\n")
io.write(w, #load("footer.txt.html"))
if include_directory_js {
io.write_string(w, `
<script type="text/javascript">
(function (win, doc) {
'use strict';
if (!doc.querySelectorAll || !win.addEventListener) {
// doesn't cut the mustard.
return;
}
let toggles = doc.querySelectorAll('[aria-controls]');
for (let i = 0; i < toggles.length; i = i + 1) {
let toggleID = toggles[i].getAttribute('aria-controls');
if (doc.getElementById(toggleID)) {
let togglecontent = doc.getElementById(toggleID);
togglecontent.setAttribute('aria-hidden', 'true');
togglecontent.setAttribute('tabindex', '-1');
toggles[i].setAttribute('aria-expanded', 'false');
}
let toggles = doc.querySelectorAll('[aria-controls]');
for (let i = 0; i < toggles.length; i = i + 1) {
let toggleID = toggles[i].getAttribute('aria-controls');
if (doc.getElementById(toggleID)) {
let togglecontent = doc.getElementById(toggleID);
togglecontent.setAttribute('aria-hidden', 'true');
togglecontent.setAttribute('tabindex', '-1');
toggles[i].setAttribute('aria-expanded', 'false');
}
}
function toggle(ev) {
ev = ev || win.event;
var target = ev.target || ev.srcElement;
if (target.hasAttribute('data-aria-owns')) {
let toggleIDs = target.getAttribute('data-aria-owns').match(/[^ ]+/g);
toggleIDs.forEach(toggleID => {
if (doc.getElementById(toggleID)) {
ev.preventDefault();
let togglecontent = doc.getElementById(toggleID);
if (togglecontent.getAttribute('aria-hidden') == 'true') {
togglecontent.setAttribute('aria-hidden', 'false');
target.setAttribute('aria-expanded', 'true');
if (target.tagName == 'A') {
togglecontent.focus();
}
} else {
togglecontent.setAttribute('aria-hidden', 'true');
target.setAttribute('aria-expanded', 'false');
}
function toggle(ev) {
ev = ev || win.event;
var target = ev.target || ev.srcElement;
if (target.hasAttribute('data-aria-owns')) {
let toggleIDs = target.getAttribute('data-aria-owns').match(/[^ ]+/g);
toggleIDs.forEach(toggleID => {
if (doc.getElementById(toggleID)) {
ev.preventDefault();
let togglecontent = doc.getElementById(toggleID);
if (togglecontent.getAttribute('aria-hidden') == 'true') {
togglecontent.setAttribute('aria-hidden', 'false');
target.setAttribute('aria-expanded', 'true');
if (target.tagName == 'A') {
togglecontent.focus();
}
} else {
togglecontent.setAttribute('aria-hidden', 'true');
target.setAttribute('aria-expanded', 'false');
}
})
}
}
})
}
doc.addEventListener('click', toggle, false);
}(this, this.document));
</script>
`)
fmt.wprintf(w, "</div></body>\n</html>\n")
}
doc.addEventListener('click', toggle, false);
}(this, this.document));
</script>`)
}
fmt.wprintf(w, "</body>\n</html>\n")
}
main :: proc() {
@@ -220,7 +211,7 @@ main :: proc() {
strings.reset_builder(&b)
write_html_header(w, "core library - pkg.odin-lang.org")
write_core_directory(w)
write_html_footer(w)
write_html_footer(w, true)
os.make_directory("core", 0)
os.write_entire_file("core/index.html", b.buf[:])
}
@@ -229,7 +220,7 @@ main :: proc() {
strings.reset_builder(&b)
write_html_header(w, fmt.tprintf("package %s - pkg.odin-lang.org", path))
write_pkg(w, path, pkg)
write_html_footer(w)
write_html_footer(w, false)
recursive_make_directory(path, "core")
os.write_entire_file(fmt.tprintf("core/%s/index.html", path), b.buf[:])
}
@@ -297,10 +288,19 @@ write_core_directory :: proc(w: io.Writer) {
}
}
fmt.wprintln(w, `<div class="row odin-main">`)
defer fmt.wprintln(w, `</div>`)
fmt.wprintln(w, `<article class="col-lg-12 p-4">`)
defer fmt.wprintln(w, `</article>`)
fmt.wprintln(w, "<h2>Directories</h2>")
fmt.wprintln(w, "<article>")
fmt.wprintln(w, "<header>")
fmt.wprintln(w, "<h1>Core Library Collection</h1>")
fmt.wprintln(w, "</header>")
fmt.wprintln(w, "</article>")
fmt.wprintln(w, "\t<table class=\"documentation-directory\">")
fmt.wprintln(w, "<div>")
fmt.wprintln(w, "\t<table class=\"doc-directory mt-4 mb-4\">")
fmt.wprintln(w, "\t\t<tbody>")
for dir := root.first_child; dir != nil; dir = dir.next {
@@ -356,6 +356,7 @@ write_core_directory :: proc(w: io.Writer) {
fmt.wprintln(w, "\t\t</tbody>")
fmt.wprintln(w, "\t</table>")
fmt.wprintln(w, "</div>")
}
is_entity_blank :: proc(e: doc.Entity_Index) -> bool {
@@ -817,23 +818,42 @@ write_docs :: proc(w: io.Writer, pkg: ^doc.Pkg, docs: string) {
}
write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_breadcrumbs :: proc(w: io.Writer, path: string) {
dirs := strings.split(path, "/")
io.write_string(w, "<ul class=\"documentation-breadcrumb\">\n")
for dir, i in dirs {
url := strings.join(dirs[:i+1], "/")
short_path := strings.join(dirs[1:i+1], "/")
if i == 0 || short_path in pkgs_to_use {
fmt.wprintf(w, "<li><a href=\"/%s\">%s</a></li>", url, dir)
} else {
fmt.wprintf(w, "<li>%s</li>", dir)
fmt.wprintln(w, `<div class="row odin-main">`)
defer fmt.wprintln(w, `</div>`)
{ // breadcrumbs
fmt.wprintln(w, `<nav class="col-lg-2 odin-side-bar-border navbar-light">`)
fmt.wprintln(w, `<div class="sticky-top odin-below-navbar py-3">`)
{
dirs := strings.split(path, "/")
io.write_string(w, "<ul class=\"nav nav-pills d-flex flex-column\">\n")
io.write_string(w, `<li class="nav-item"><a class="nav-link" href="/core">core</a></li>`)
for dir, i in dirs {
url := strings.join(dirs[:i+1], "/")
short_path := strings.join(dirs[1:i+1], "/")
io.write_string(w, `<li class="nav-item">`)
a_class := "nav-link"
if i+1 == len(dirs) {
a_class = "nav-link active"
}
if i == 0 || short_path in pkgs_to_use {
fmt.wprintf(w, `<a class="%s" href="/core/%s">%s</a></li>` + "\n", a_class, url, dir)
} else {
fmt.wprintf(w, "%s</li>\n", dir)
}
}
io.write_string(w, "</ul>\n")
}
io.write_string(w, "</ul>\n")
fmt.wprintln(w, `</div>`)
fmt.wprintln(w, `</nav>`)
}
write_breadcrumbs(w, fmt.tprintf("core/%s", path))
fmt.wprintln(w, `<article class="col-lg-8 p-4">`)
fmt.wprintf(w, "<h1>package core:%s</h1>\n", path)
fmt.wprintln(w, "<h2>Documentation</h2>")
@@ -847,7 +867,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
}
fmt.wprintln(w, "<h3>Index</h3>")
fmt.wprintln(w, `<section class="documentation-index">`)
fmt.wprintln(w, `<section class="doc-index">`)
pkg_procs: [dynamic]^doc.Entity
pkg_proc_groups: [dynamic]^doc.Entity
pkg_types: [dynamic]^doc.Entity
@@ -883,7 +903,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_index :: proc(w: io.Writer, name: string, entities: []^doc.Entity) {
fmt.wprintf(w, "<h4>%s</h4>\n", name)
fmt.wprintln(w, `<section class="documentation-index">`)
fmt.wprintln(w, `<section class="doc-index">`)
if len(entities) == 0 {
io.write_string(w, "<p>This section is empty.</p>\n")
} else {
@@ -933,11 +953,11 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
name := str(e.name)
path := pkg_to_path[pkg]
filename := slashpath.base(str(files[e.pos.file].name))
fmt.wprintf(w, "<h4 id=\"{0:s}\"><span><a class=\"documentation-id-link\" href=\"#{0:s}\">{0:s}", name)
fmt.wprintf(w, "<h4 id=\"{0:s}\"><span><a class=\"doc-id-link\" href=\"#{0:s}\">{0:s}", name)
fmt.wprintf(w, "<span class=\"a-hidden\">&nbsp;¶</span></a></span>")
if e.pos.file != 0 && e.pos.line > 0 {
src_url := fmt.tprintf("%s/%s/%s#L%d", GITHUB_CORE_URL, path, filename, e.pos.line)
fmt.wprintf(w, "<div class=\"documentation-source\"><a href=\"{0:s}\"><em>Source</em></a></div>", src_url)
fmt.wprintf(w, "<div class=\"doc-source\"><a href=\"{0:s}\"><em>Source</em></a></div>", src_url)
}
fmt.wprintf(w, "</h4>\n")
@@ -945,7 +965,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
case .Invalid, .Import_Name, .Library_Name:
// ignore
case .Constant:
fmt.wprint(w, "<pre>")
fmt.wprint(w, `<pre class="doc-code">`)
the_type := types[e.type]
init_string := str(e.init_string)
@@ -973,7 +993,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
io.write_string(w, init_string)
fmt.wprintln(w, "</pre>")
case .Variable:
fmt.wprint(w, "<pre>")
fmt.wprint(w, `<pre class="doc-code">`)
write_attributes(w, e)
fmt.wprintf(w, "%s: ", name)
write_type(writer, types[e.type], {.Allow_Indent})
@@ -985,7 +1005,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintln(w, "</pre>")
case .Type_Name:
fmt.wprint(w, "<pre>")
fmt.wprint(w, `<pre class="doc-code">`)
fmt.wprintf(w, "%s :: ", name)
the_type := types[e.type]
type_to_print := the_type
@@ -1004,14 +1024,14 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_type(writer, type_to_print, {.Allow_Indent})
fmt.wprintln(w, "</pre>")
case .Procedure:
fmt.wprint(w, "<pre>")
fmt.wprint(w, `<pre class="doc-code">`)
fmt.wprintf(w, "%s :: ", name)
write_type(writer, types[e.type], nil)
write_where_clauses(w, array(e.where_clauses))
fmt.wprint(w, " {…}")
fmt.wprintln(w, "</pre>")
case .Proc_Group:
fmt.wprint(w, "<pre>")
fmt.wprint(w, `<pre class="doc-code">`)
fmt.wprintf(w, "%s :: proc{{\n", name)
for entity_index in array(e.grouped_entities) {
this_proc := &entities[entity_index]
@@ -1035,7 +1055,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_docs(w, pkg, strings.trim_space(str(e.docs)))
}
write_entities :: proc(w: io.Writer, title: string, entities: []^doc.Entity) {
fmt.wprintf(w, "<h3>%s</h3>\n", title)
fmt.wprintf(w, "<h3 id=\"pkg-{0:s}\">{0:s}</h3>\n", title)
fmt.wprintln(w, `<section class="documentation">`)
if len(entities) == 0 {
io.write_string(w, "<p>This section is empty.</p>\n")
@@ -1054,7 +1074,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_entities(w, "Constants", pkg_consts[:])
fmt.wprintln(w, "<h3>Source Files</h3>")
fmt.wprintln(w, `<h3 id="pkg-source-files">Source Files</h3>`)
fmt.wprintln(w, "<ul>")
any_hidden := false
source_file_loop: for file_index in array(pkg.files) {
@@ -1087,4 +1107,38 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
}
fmt.wprintln(w, "</ul>")
fmt.wprintln(w, `</article>`)
{
write_link :: proc(w: io.Writer, id, text: string) {
fmt.wprintf(w, `<li><a href="#%s">%s</a>`, id, text)
}
write_index :: proc(w: io.Writer, name: string, entities: []^doc.Entity) {
fmt.wprintf(w, `<li><a href="#pkg-{0:s}">{0:s}</a>`, name)
fmt.wprintln(w, `<ul>`)
for e in entities {
name := str(e.name)
fmt.wprintf(w, "<li><a href=\"#{0:s}\">{0:s}</a></li>\n", name)
}
fmt.wprintln(w, "</ul>")
fmt.wprintln(w, "</li>")
}
fmt.wprintln(w, `<div class="col-lg-2 odin-toc-border navbar-light"><div class="sticky-top odin-below-navbar py-3">`)
fmt.wprintln(w, `<nav id="TableOfContents">`)
fmt.wprintln(w, `<ul>`)
write_link(w, "pkg-overview", "Overview")
write_index(w, "Procedures", pkg_procs[:])
write_index(w, "Procedure Groups", pkg_proc_groups[:])
write_index(w, "Types", pkg_types[:])
write_index(w, "Variables", pkg_vars[:])
write_index(w, "Constants", pkg_consts[:])
write_link(w, "pkg-source-files", "Source Files")
fmt.wprintln(w, `</ul>`)
fmt.wprintln(w, `</nav>`)
fmt.wprintln(w, `</div></div>`)
}
}

View File

@@ -1,26 +1,18 @@
html {
font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
}
/* doc directories */
.container {
max-width: 60em;
margin: 0 auto;
padding-left: 0.01em 1em;
}
table.documentation-directory {
table.doc-directory {
/*border: 1px solid #ccc!important;*/
table-layout: fixed;
border-collapse: collapse;
}
.documentation-directory tr {
.doc-directory tr {
padding-left: 1em!important;
border-top: 1px solid #ccc!important;
border-bottom: 1px solid #ccc!important;
}
.documentation-directory td {
.doc-directory td {
padding: 0.25em 0.5em;
}
.directory-child td {
@@ -32,59 +24,62 @@ table.documentation-directory {
left: -1.5em!important;
padding-right: 0;
}
.pkg-line-doc {
color: #444;
}
.documentation-directory tr[aria-controls]:hover {
.doc-directory tr[aria-controls]:hover {
background-color: #eee;
}
.documentation-directory tr[aria-expanded=true] td.pkg-name:before {
.doc-directory tr[aria-expanded=true] td.pkg-name:before {
content: "\2193";
}
.documentation-directory tr[aria-expanded=false] td.pkg-name:before {
.doc-directory tr[aria-expanded=false] td.pkg-name:before {
content: "\2192"!important;
}
.documentation-directory tr[aria-hidden=true] {
.doc-directory tr[aria-hidden=true] {
display: none;
}
pre {
/* doc page */
pre.doc-code {
white-space: pre-wrap;
word-break: keep-all;
word-wrap: break-word;
tab-size: 8;
font-family: Consolas,Liberation Mono,Menlo,monospace!important;
background-color: #f8f8f8;
color: #202224;
border: 1px solid #c6c8ca;
border-radius: 0.25rem;
padding: 0.625rem;
}
pre a {
pre.doc-code a {
font-family: Consolas,Liberation Mono,Menlo,monospace!important;
text-decoration: none;
/*font-weight: bold;*/
color: #00bfd5;
}
.documentation pre a.code-procedure {
pre.doc-code a.code-procedure {
color: #079300;
}
.documentation-source {
.pkg-line-doc {
color: #444;
}
.doc-source {
display: inline;
float: right;
}
.documentation-source a {
.doc-source a {
text-decoration: none;
color: #666666;
}
.documentation-source a:hover {
.doc-source a:hover {
text-decoration: underline;
}
@@ -95,42 +90,6 @@ a:hover > .a-hidden {
opacity: 100;
}
ul.documentation-breadcrumb {
list-style: none;
}
ul.documentation-breadcrumb li {
display: inline;
}
ul.documentation-breadcrumb li+li:before {
padding: 0.2rem;
color: black;
content: "/\00a0";
}
.code-inline {
font-family: Consolas,Liberation Mono,Menlo,monospace!important;
background-color: #f8f8f8;
color: #202224;
border: 1px solid #c6c8ca;
border-radius: 0.25rem;
padding: 0.125rem;
}
.documentation-directory {
width: 100%;
}
.documentation-directory tr {
/*background-color: #999;*/
}
.documentation-directory tr[aria-controls] {
cursor: pointer;
}
.documentation-directory tr.hidden {
display: none;
.documentation h4 {
font-size: calc(1.1rem + .2vw);
}