Added a new tool that can generate a simple locally runnable markdeep based site from the docs.

This commit is contained in:
Relintai 2024-03-16 16:05:17 +01:00
parent 778505a930
commit 4439456d7b
8 changed files with 540 additions and 0 deletions

2
.gitignore vendored
View File

@ -8,6 +8,8 @@ __pycache__
.vscode/
*.mo
out/
# Vim temp files
*.swo
*.swp

25
_tools/markdeep/LICENSE Normal file
View File

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2020, Morgan McGuire
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,7 @@
<meta charset="utf-8">
DOCUMENT_BODY
<script>markdeepOptions = {tocStyle: 'long'};</script>
<link rel="stylesheet" href="slate.css">
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>

View File

@ -0,0 +1,11 @@
<meta charset="utf-8">
**DOCUMENT_TITLE**
[&lt-- Back to Documentation Index](DOCUMENT_PATHindex.html)
DOCUMENT_BODY
<script>markdeepOptions = {tocStyle: 'long'};</script>
<link rel="stylesheet" href="DOCUMENT_PATHslate.css">
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="DOCUMENT_PATHmarkdeep.min.js"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>

10
_tools/markdeep/markdeep.min.js vendored Normal file

File diff suppressed because one or more lines are too long

249
_tools/markdeep/slate.css Normal file
View File

@ -0,0 +1,249 @@
body#md {
font-weight: 400;
font-size: 16px;
font-family: Arial, Helvetica, "sans serif";
text-align: left;
line-height: 170%;
}
/* reset heading/link fonts to that of body */
.md a,
.md div.title, contents, .md .tocHeader,
.md h1, .md h2, .md h3, .md h4, .md h5, .md h6,
.md .nonumberh1, .md .nonumberh2, .md .nonumberh3, .md .nonumberh4, .md .nonumberh5, .md .nonumberh6,
.md .shortTOC, .md .mediumTOC, .md .longTOC {
font-family: inherit;
}
.md .tocHeader {
border: none;
margin-top: 25px;
font-size: 100%;
font-family: inherit;
font-weight: 300;
}
.md .longTOC .level1 {
font-weight: 300;
margin-bottom: -30px;
}
.md div.title, .md div.subtitle, .md h1, .md h2, .md h3, .md h4, .md h5, .md h6 {
font-family: Arial, Helvetica, "sans serif";
font-weight: 300;
}
.md div.title {
font-size: 43px;
text-align: left;
margin-bottom: 0px;
}
.md div.subtitle {
text-align: left;
font-size: 115%;
}
.md div.afterTitles {
margin-top: 20px;
margin-left: -20px;
margin-right: -20px;
height: 0px;
border-bottom: 1px solid #000;
box-shadow: 0px 1px 2px rgba(0,0,0,0.5);
}
.md div.afterTitles + p {
margin-top: 30px;
}
.md h1 {
font-size: 175%;
margin-bottom: 25px;
margin-left:-20px;
margin-right:-20px;
padding-left:20px;
padding-top:25px;
border-bottom: none;
border-top:6px solid #5a5a5a;
}
.md h2 {
font-size: 150%;
border: none;
}
.md h3, .md h4, .md h5, .md h6 {
font-size: 120%;
}
.md code {
font-size: 90%;
background: #eee;
padding-left: 2px;
padding-right: 2px;
}
.md .longTOC {
font-family: 'Roboto', Arial, Helvetica, "sans serif";
font-weight: 300;
}
.md pre.listing {
font-size: 100%;
}
.md pre.listing code {
font-weight: unset;
background: none;
color: unset;
}
/* Darkmode, wide screen: TOC on side */
@media screen and (min-device-width: 600px) {
.md .longTOC {
display: block;
white-space: nowrap;
width: 170px;
border-right: 1px solid #777;
overflow-y:scroll;
font-family: inherit;
background: #202020;
position: fixed;
left: 0px;
top: 0px;
bottom:0px;
margin: 0px;
padding: 0px;
padding-left:10px;
}
body {
position: absolute;
left: 200px;
right:0px;
margin: 0px;
padding: 0px;
max-width: unset;
padding-right: 15px;
}
}
/* Dark mode with side TOC on screen */
@media screen {
.md div.longTOC {
font-size: 15px;
}
.md svg.diagram {
stroke: #ccc;
fill: #ccc;
}
.md svg.diagram .opendot {
fill: #000;
}
.md table.table {
box-shadow: 0px 1px 2px rgba(0,0,0,0.5);
background-color: #2a2a2a;
}
.md table.table tr:nth-child(even) {
background-color: #202020;
}
.md table.table td, .md table.table th {
border: 1px solid #202020;
}
.md table.table th {
color: #000;
}
.md pre.listing {
background: #202020;
border: 1px solid #777;
box-shadow: 0px 1px 2px rgba(0,0,0,0.5);
}
.md code {
color: #fff;
background: unset;
}
.md .tocTop {
display: inline;
}
.md div.afterTitles {
border-bottom: 1px solid #fff;
}
.md div.title, .md div.subtitle, .md h1, .md h2, .md h3, .md h4, .md h5, .md h6 {
color: #fff;
}
.hljs-comment,.hljs-quote{color:#a0f0aa}.hljs-variable,.hljs-template-variable,.hljs-tag,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-deletion{color:#cc6666}.hljs-number,.hljs-built_in,.hljs-builtin-name,.hljs-literal,.hljs-type,.hljs-params,.hljs-meta,.hljs-link{color:#de935f}.hljs-attribute{color:#f0c674}.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#b5bd68}.hljs-title,.hljs-section{color:#81a2be}.hljs-keyword,.hljs-selector-tag{color:#b294bb}.hljs{display:block;overflow-x:auto;background:#1d1f21;color:#c5c8c6;padding:.5em}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
.hljs-function .hljs-title { color:#81a2be}
body {
color: #ccc;
background: #3a3a3a;
}
.md div.title, .md h1, .md h2, .md h3, .md h4, .md h5, .md h6, .md .longTOC a, .md .longTOC code, .md a:link, .md a:visited {
text-shadow: 0px 1px 2px rgba(0,0,0,0.5);
}
.md .admonition {
position: unset;
box-shadow: 0px 1px 2px rgba(0,0,0,0.5);
background: #202020;
border: 1px solid rgba(68,138,255,1);
border-left: 2.5rem solid rgba(68,138,255,1);
}
.md .admonition-title {
border-bottom: 1px solid rgba(68,138,255,1);
}
.md .admonition.warn, .md .admonition.warning {
border: 1px solid rgba(255,170,0,1);
border-left: 2.5rem solid rgba(255,170,0,1);
background: #202020;
}
.md .admonition.warn .admonition-title, .md .admonition.warning .admonition-title {
border-bottom: 1px solid rgba(68,138,255,1);
}
.md .admonition.tip {
border: 1px solid rgba(68,138,255,1);
border-left: 2.5rem solid rgba(68,138,255,1);
background: #202020;
}
.md .admonition.tip .admonition-title {
border-bottom: 1px solid rgba(68,138,255,1);
}
.md .admonition.error {
border: 1px solid rgba(255,23,68,1);
border-left: 2.5rem solid rgba(255,23,68,1);
background: #202020;
}
.md .admonition.error .admonition-title {
border-bottom: 1px solid rgba(255,23,68,1);
}
.md .longTOC a, .md .longTOC code, .md a:link, .md a:visited, .md a:link code, .md a:visited code {
color: #80bfff !important;
}
}

View File

@ -0,0 +1,3 @@
https://github.com/morgan3d/markdeep/tree/master
1.16

233
_tools/md_doc_gen.py Normal file
View File

@ -0,0 +1,233 @@
from os import listdir
from os.path import isfile, join
import os
import sys
from shutil import copyfile
input_folder = "./"
output_base_folder = "out"
output_folder = output_base_folder + "/"
main_body_template = ""
index_body_template = ""
processed_files = []
def read_file(path):
f = open(path, "r")
data = f.read()
f.close()
return data
def write_file(path, data):
f = open(path, "w")
f.write(data)
f.close()
def ensure_dir(storage_path):
if not os.path.exists(storage_path):
os.makedirs(storage_path)
def categ_to_name(name):
ns = name.split("_")
try:
# if it's an int, remove it, so sorting can be done via prefixing folders with numbers
ii = int(ns[0])
n = ns[1]
for i in range(2, len(ns)):
n += "_" + ns[i]
name = n
except:
pass
name = name.replace("_", " ").title()
name = name.replace("2d", "2D").replace("3d", "3D").replace("Faq", "FAQ")
return name
def link_to_name(name):
name = name.split("/")[-1]
name = name.replace(".md.html", "")
ns = name.split("_")
try:
# if it's an int, remove it, so sorting can be done via prefixing folders with numbers
ii = int(ns[0])
n = ns[1]
for i in range(2, len(ns)):
n += "_" + ns[i]
name = n
except:
pass
name = name.replace("_", " ").title()
name = name.replace("2d", "2D").replace("3d", "3D").replace("Faq", "FAQ")
return name
def strip_path_sort_number(name):
try:
# if it's an int, remove it, so sorting can be done via prefixing folders with numbers
ii = int(ns[0])
n = ns[1]
for i in range(2, len(ns)):
n += "_" + ns[i]
name = n
except:
pass
return name
def path_to_document_name(name):
name = name.removeprefix(os.getcwd() + "/out/")
ns = name.split("/")
final = ""
for i in range(len(ns) - 1):
final += strip_path_sort_number(ns[i].replace("_", " ")).title() + " / "
final += strip_path_sort_number(ns[-1].replace(".md", "").replace("_", " ")).title()
final = final.replace("2d", "2D").replace("3d", "3D").replace("Faq", "FAQ")
return final
def process_md(inf, outf, depth):
global processed_files
fd = read_file(inf)
dp = ""
for i in range(depth):
dp += "../"
data = main_body_template.replace("DOCUMENT_PATH", dp)
data = data.replace("DOCUMENT_TITLE", path_to_document_name(outf))
data = data.replace("DOCUMENT_BODY", fd)
write_file(outf + ".html", data)
processed_files.append(outf + ".html")
def process_dir_copy(d, out_fol, depth):
files = os.listdir(d)
for f in files:
inf = os.path.abspath(d + f)
outf = os.path.abspath(out_fol + f)
if os.path.isdir(inf):
continue
if f.lower().endswith(".md"):
print("Processing: " + f)
process_md(inf, outf, depth)
continue
#print(inf)
#print(outf)
print("Copying: " + inf)
copyfile(inf, outf)
def process_dirs(proc_dir, out_fol, depth, skip_fol = []):
cdirarr = os.listdir(proc_dir)
for d in cdirarr:
if d in skip_fol:
continue
p = os.path.abspath(proc_dir + d)
out_p = os.path.abspath(out_fol + d)
if os.path.isdir(p):
ensure_dir(out_p)
process_dirs(p + "/", out_p + "/", depth + 1)
process_dir_copy(p + "/", out_p + "/", depth)
def process_category(categ_dict, category_level):
result = ""
keys = list(categ_dict.keys())
keys.sort()
for k in keys:
categ = categ_dict[k]
if isinstance(categ, dict):
result += "\n"
for i in range(category_level):
result += "#"
result += " " + categ_to_name(k) + "\n"
result += "\n"
result += process_category(categ, category_level + 1)
else:
cs = categ.split(";")
cs.sort()
for c in cs:
result += "\n"
result += "[" + link_to_name(c) + "](" + c + ")"
result += "\n"
return result
main_body_template = read_file("./_tools/markdeep/main_body.md.html")
index_body_template = read_file("./_tools/markdeep/index_body.md.html")
ensure_dir(output_folder)
process_dirs(input_folder, output_folder, 1, [ output_base_folder, "_tools", ".git" ])
copyfile("./_tools/markdeep/slate.css", output_folder + "slate.css")
copyfile("./_tools/markdeep/markdeep.min.js", output_folder + "markdeep.min.js")
current_dir = os.getcwd() + "/out/"
files = []
for f in processed_files:
files.append(f.removeprefix(current_dir))
file_categories = {}
for f in files:
fs = f.split("/")
d = file_categories
for i in range(len(fs) - 1):
if not fs[i] in d:
d[fs[i]] = {}
d = d[fs[i]]
if fs[-2] in d:
d[fs[-2]] = d[fs[-2]] + ";" + f
else:
d[fs[-2]] = f
fd = process_category(file_categories, 1)
data = index_body_template.replace("DOCUMENT_BODY", fd)
write_file("out/index.html", data)