The big documentation system overhaul

This commit is contained in:
K. Lange 2021-02-20 14:10:36 +09:00
parent 32b957aff7
commit d5d3d721e7
17 changed files with 1418 additions and 70 deletions

3
.gitignore vendored
View File

@ -7,7 +7,8 @@
/wasm/
/jupyter/
# Doxygen output
/html/
/docs/html/
/docs/mod*.md
# Match library files anywhere.
*.o
*.so

View File

@ -1,30 +0,0 @@
PROJECT_NAME = "Kuroko"
PROJECT_BRIEF = "Bytecode-compiled interpreted programming language."
PROJECT_LOGO =
# Since we're documenting a C API...
OPTIMIZE_OUTPUT_FOR_C = YES
LAYOUT_FILE =
# Make docs for interpreter and tools
INPUT = src/ tools/
# Ignore rline, since it's a vendored library from ToaruOS
EXCLUDE = src/rline.c src/rline.h
# Enable the source browser, even if I don't particular like Doxygen's highlighting
SOURCE_BROWSER = YES
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 0
HTML_COLORSTYLE_SAT = 200
# Doxygen will enable latex by default, so let's turn that off.
GENERATE_LATEX = NO

View File

@ -108,6 +108,7 @@ modules/math.so: src/module_math.c libkuroko.so
.PHONY: clean
clean:
@rm -f ${OBJS} ${TARGET} ${MODULES} libkuroko.so src/*.o kuroko.exe ${TOOLS} $(patsubst %,%.exe,${TOOLS})
@rm -rf docs/html
tags: $(wildcard src/*.c) $(wildcard src/*.h)
@ctags --c-kinds=+lx src/*.c src/*.h
@ -175,3 +176,9 @@ deb: kuroko libkuroko.so
--iteration 0 \
--directories $(libdir)/kuroko
rm -r $(DESTDIR)
.PHONY: docs
docs: kuroko
./kuroko tools/gendoc.krk
doxygen docs/Doxyfile

39
docs/Doxyfile Normal file
View File

@ -0,0 +1,39 @@
PROJECT_NAME = "Kuroko"
PROJECT_BRIEF = "Bytecode-compiled interpreted programming language."
PROJECT_LOGO =
# Since we're documenting a C API...
OPTIMIZE_OUTPUT_FOR_C = YES
LAYOUT_FILE = docs/DoxygenLayout.xml
# Make docs for interpreter and tools
INPUT = src/ tools/ docs/
FILE_PATTERNS = *.c *.h *.md
# Ignore rline, since it's a vendored library from ToaruOS
EXCLUDE = src/rline.c src/rline.h
# Enable the source browser, even if I don't particular like Doxygen's highlighting
SOURCE_BROWSER = YES
GENERATE_HTML = YES
HTML_OUTPUT = docs/html
HTML_FILE_EXTENSION = .html
HTML_HEADER = docs/doxygen_header.html
HTML_FOOTER = docs/doxygen_footer.html
HTML_EXTRA_FILES = docs/doxy.css docs/tabs-override.css
HTML_COLORSTYLE_HUE = 0
HTML_COLORSTYLE_SAT = 200
# Doxygen will enable latex by default, so let's turn that off.
GENERATE_LATEX = NO
ALIASES += methodstart{4}="\htmlonly<\3 class=\"memtitle \4\" id=\"\1\"><span class=\"permalink\"><a href=\"#\1\">_</a></span>\2</\3><div class=\"memitem\"><div class=\"memdoc\">\endhtmlonly"
ALIASES += methodend="\htmlonly</div></div>\endhtmlonly"
ALIASES += bsnote{1}="\htmlonly<div class=\"alert alert-warning\">\endhtmlonly\1\htmlonly</div>\endhtmlonly"
ALIASES += modulelist{1}="\htmlonly<div class=\"directory\"><table class=\"directory\">\endhtmlonly\1\htmlonly</table></div>\endhtmlonly"
ALIASES += krkmodule{2}="\htmlonly<tr class=\"autoalternate\"><td class=\"entry\"><span style\"width:16px;display:inline-block;\">&nbsp;</span><span class=\"icona\"><span class=\"icon\">M</span></span>\endhtmlonly@ref \1\htmlonly</td><td class=\"desc\">\endhtmlonly\2\htmlonly</td</tr>\endhtmlonly"
# These are just really crazy
COLLABORATION_GRAPH = NO

233
docs/DoxygenLayout.xml Normal file
View File

@ -0,0 +1,233 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.17 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title="Home"/>
<tab type="usergroup" visible="yes" url="@ref embedding" title="Embedding">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="usergroup" visible="yes" title="Modules">
<tab type="user" url="@ref modulelist" title="Module List"/>
</tab>
<!--
<tab type="pages" visible="no" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="Modules">
<tab type="namespacelist" visible="yes" title="Module List" intro=""/>
<tab type="namespacemembers" visible="yes" title="Module Members" intro=""/>
</tab>
<tab type="interfaces" visible="yes" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="C API">
</tab>
<tab type="structs" visible="yes" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="yes" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
-->
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

355
docs/doxy.css Normal file
View File

@ -0,0 +1,355 @@
#main-nav {
height: 40px;
background-color: rgb(33, 37, 41); /* Main bootstrap nav background color */
border-radius: 5px;
color: #fff;
display: flex;
}
#main-nav li {
list-style: none;
font-size: 14px;
}
#main-menu {
align-items: center;
border-radius: 5px;
height: 100%;
display: flex;
flex-direction: row;
width: 100%;
}
#main-menu>li:last-child {
margin-left: auto;
}
#main-menu div#MSearchBox {
display: flex;
margin-top: 0;
height: 19px;
}
#MSearchBox>span {
top: auto !important;
}
#MSearchBox>span.left {
border-radius: 5px 0px 0px 5px;
background-color: #fff;
background-image: none;
}
#MSearchBox>span>input {
background-image: none;
background-color: #fff;
}
#MSearchBox>span.right {
top: auto;
border-radius: 0px 5px 5px 0px;
background-color: #fff;
background-image: none;
}
.header {
margin-top: 1em;
}
.header a { text-decoration: none; }
.header a:hover { text-decoration: underline; }
.header>.summary {
float: right;
font-size: small;
}
.header>.headertitle {
font-size: 25px;
font-weight: bold;
}
.contents {
margin-bottom: 2rem;
}
.contents a { text-decoration: none; }
.contents a:hover { text-decoration: underline; }
.contents h1 {
font-size: 32px;
font-weight: bold;
margin-top: 1rem;
}
.contents h2 {
font-size: 26px;
}
.contents a {
scroll-margin-top: 4rem;
}
tr.heading h2 {
margin-top: 12px;
margin-bottom: 4px;
}
h2.groupheader {
margin-top: 1.75em;
}
.contents .center {
text-align: center;
}
.legend {
}
h3.classDef, h3.letDef {
font-size: 22px;
}
h3.classDef>em, h3.letDef>em {
font-size: 18px;
}
h3.classDef>b, h3.letDef>b {
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
}
table.memberdecls {
border-spacing: 0px;
padding: 0;
}
.memItemLeft { white-space: nowrap; }
.memItemRight { width: 100%; }
.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams {
margin: 4px;
background-color: #fef7f7;
border: none;
padding: 1px 0 0 8px;
}
.memSeparator {
border-bottom: 1px solid #f9d5d5;
line-height: 1px;
margin: 0;
padding: 0;
}
a.el {
font-weight: bold;
color: rgb(179,21,21);
}
h2.memtitle, h3.memtitle, h4.memtitle {
padding: .5rem 1rem;
margin-bottom: 0;
background-color: rgba(0,0,0,.03);
border: 1px solid rgba(0,0,0,.125);
border-radius: 5px 5px 0px 0px;
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
font-size: 24px;
scroll-margin-top: 4rem;
}
.memtitle.classDef {
background-color: #cfe2ff;
}
.memtitle.exceptionDef {
background-color: #f8d7da;
}
h4.memtitle {
font-size: 22px;
}
div.memitem {
border-radius: 0px 0px 5px 5px;
border: 1px solid rgba(0,0,0,.125);
border-top: none;
padding: 0;
margin-bottom: 0.5rem;
}
div.memproto {
background-color: rgba(0,0,0,.015);
border-bottom: 1px solid rgba(0,0,0,.125);
padding: 0.5rem;
font-size: 17px;
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
line-height: 19px;
}
div.memdoc {
padding: 0.5rem 0.5rem 0 0.5rem;
}
.params .paramname {
font-weight: bold;
}
.paramname {
color: #602020;
white-space: nowrap;
}
.params dd {
margin-left: 2rem;
}
.permalink>a {
visibility: hidden;
font-size: 0;
}
.permalink>a::before {
visibility: visible;
font-size: 24px;
content: "#";
margin-right: 0.25rem;
color: rgb(10,10,10,0.25);
}
.permalink>a:hover::before {
color: rgb(10,10,10,1);
}
.permalink>a:hover { text-decoration: none; }
.contents > hr {
display: none;
}
.icona {
width: 24px;
height: 22px;
display: inline-block;
}
.icon {
background-color: #dc3545;
font-weight: bold;
color: #fff;
font-size: 12px;
width: 18px;
border-radius: 4px;
display: inline-block;
text-align: center;
}
.directory tr:nth-child(odd) {
background-color: rgba(0,0,0,.03);
}
.directory td.desc {
width: 100%;
border-left: 1px solid rgba(0,0,0,0.05);
padding-left: 1rem;
}
.directory td.entry {
white-space: nowrap;
padding-right: 6px;
padding-top: 3px;
}
.arrow {
user-select: none;
cursor: pointer;
font-size: 80%;
display: inline-block;
width: 16px;
height: 22px;
}
.levels {
white-space: nowrap;
text-align: right;
font-size: 9pt;
}
.levels>span {
cursor: pointer;
padding-left: 2px;
padding-right: 2px;
color: #B31515;
}
.qindex {
text-align: center;
color: #fff;
display: none;
}
.qindex>a {
}
.classindex {
width: 100%;
}
.classindex .ah {
display: inline-block;
width: 25px;
height: 25px;
border-radius: 4px;
background-color: rgb(0,0,0,0.05);
color: #602020;
font-weight: bold;
}
.fragment>.line {
font-size: 17px;
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
line-height: 19px;
white-space: pre-wrap;
}
.fragment {
margin: 1rem;
background-color: #1f1f1f;
padding: 0.5rem;
border-radius: 5px;
color: #e6e6e6;
}
.fragment a {
color: inherit;
text-decoration: underline;
text-decoration-style: dotted;
}
.fragment>.line {
margin: 0;
padding: 0;
line-height: normal;
}
.fragment>.line span.keyword { color: #33a2e6; }
.fragment>.line span.keywordflow { color: #33a2e6; }
.fragment>.line span.stringliteral { color: #48b048; }
.fragment>.line span.comment { color: #9e9981; font-style: oblique; }
.fragment>.line span.numeric { color: #e62b7f; }
.fragment>.line span.charliteral { color: #e62b7f; }
.fragment>.line span.escape { color: #71cbad; }
.fragment>.line span.keywordtype { color: #e6ce6e; }
.fragment>.line span.preprocessor { color: #e62b7f; }
.fragment>.line>.lineno {
color: #e6ce6e; background-color: #1f1f1f;
border-right: 1px solid rgb(255,255,255,0.5);
padding-right: 0.5rem;
}
.fragment>.line>.lineno a {
text-decoration: none;
}
.ttc {
position: absolute;
display: none;
}
#powerTip {
cursor: default;
white-space: nowrap;
background-color: white;
border: 1px solid #d8d8d8;
border-radius: calc(.3rem - 1px);
box-shadow: 1px 1px 7px black;
display: none;
font-size: smaller;
max-width: 80%;
background-color: rgba(255,255,255,0.9);
padding: 0;
position: absolute;
z-index: 2147483647;
}
#powerTip>.ttname {
background-color: #f0f0f0;
padding: 0.5rem 1rem;
border-bottom: 1px solid #d8d8d8;
}
#powerTip>.ttname a {
text-decoration: none;
color: inherit;
}
#powerTip>.ttdeci {
padding: 0.5rem 1rem;
background-color: #fff;
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
}
#powerTip>.ttdoc {
padding: 0.5rem 1rem;
background-color: #fff;
}
#powerTip>.ttdef {
padding: 0.5rem 1rem;
border-top: 1px solid #d8d8d8;
background-color: #f0f0f0;
}
#nav-path ul {
display: flex;
flex-direction: row;
}
#nav-path ul li {
list-style: none;
display: inline-block;
margin: 0.25rem;
margin-left: auto;
margin-right: auto;
}
#nav-path ul li + li::before {
padding-right: 0.5rem;
color: rgb(0,0,0,0.6);
content: '/';
}

7
docs/doxygen_footer.html Normal file
View File

@ -0,0 +1,7 @@
<footer class="container text-center mb-3">
<p class="mb-0">Copyright 2020-2021 <a href="https://github.com/klange">K. Lange</a></p>
<p class="mb-0">$generatedby <a href="http://www.doxygen.org/index.html"><img class="footer" style="height: 20px;" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion</p>
</footer>
</main>
</body>
</html>

67
docs/doxygen_header.html Normal file
View File

@ -0,0 +1,67 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="shortcut icon" href="/favicon.ico">
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="$relpath^tabs-override.css">
<link rel="stylesheet" href="$relpath^doxy.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<title>Docs | Kuroko</title>
<script src="/src-min/ace.js"></script>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
</head>
<body>
<!-- Bootstrap nav bar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav ms-auto mb-2 mb-md-0">
<li class="nav-item">
<a class="nav-link force-cursor" href="/?r=y&c=tutorial()">Tutorial</a>
</li>
<li class="nav-item">
<a class="nav-link force-cursor" href="/?r=y&c=license()">License</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="/" id="navbarDropdown">
Examples
</a>
</li>
</ul>
</div>
<div class="mx-auto order-0" style="padding-left: 2rem; padding-right: 2rem">
<a class="navbar-brand" href="/">
<img src="/logo.png" style="height: 2rem; padding-right: 0.5rem;">
Kuroko
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav me-auto mb-2 mb-md-0">
<li class="nav-item">
<a class="nav-link" href="https://github.com/kuroko-lang/kuroko">Github</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/kuroko-lang/kuroko/releases">Downloads</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/docs/">Docs</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- End Bootstrap nav bar -->
<main class="order-1 container" id="main-content">
<div id="top">

19
docs/embedding.md Normal file
View File

@ -0,0 +1,19 @@
## Kuroko C API Documentation {#embedding}
### Getting Started {#getting-started}
```c
#include <stdio.h>
#include <kuroko/kuroko.h>
#include <kuroko/vm.h>
int main(int argc, char *argv[]) {
krk_initVM(0);
krk_startModule("__main__");
krk_interpret("import kuroko\nprint('Kuroko',kuroko.version)\n", 1, "<stdin>","<stdin>");
krk_freeVM();
return 0;
}
```

3
docs/index.md Normal file
View File

@ -0,0 +1,3 @@
# Kuroko Language Reference {#mainpage}
Hello, world.

354
docs/tabs-override.css Normal file
View File

@ -0,0 +1,354 @@
.sm {
position:relative;
}
.sm,
.sm ul,
.sm li {
display:block;
list-style:none;
line-height:normal;
-webkit-tap-highlight-color:rgba(0,0,0,0)
}
.sm>li>h1,
.sm>li>h2,
.sm>li>h3,
.sm>li>h4,
.sm>li>h5,
.sm>li>h6 {
margin:0;
padding:0
}
.sm ul {
display:none
}
.sm li,
.sm a {
position:relative
}
.sm a {
display:block
}
.sm a.disabled {
cursor:not-allowed
}
.sm:after {
content:"\00a0";
display:block;
height:0;
font:0px/0 serif;
clear:both;
visibility:hidden;
overflow:hidden
}
.sm,
.sm *,
.sm *:before,
.sm *:after {
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box
}
.sm-dox {
}
.sm-dox a,
.sm-dox a:focus,
.sm-dox a:hover,
.sm-dox a:active {
text-decoration:none;
color: rgba(255,255,255,.55);
outline:none
}
.sm-dox a:hover {
color:#fff;
}
.sm-dox a.current {
color:#D23600
}
.sm-dox a.disabled {
color:#bbb
}
.sm-dox a span.sub-arrow {
position:absolute;
top:50%;
margin-top:-14px;
left:auto;
right:3px;
width:28px;
height:28px;
overflow:hidden;
font:bold 12px/28px monospace !important;
text-align:center;
background:rgba(255,255,255,0.5);
border-radius:5px
}
.sm-dox a.highlighted span.sub-arrow:before {
display:block;
content:'-'
}
.sm-dox>li:first-child>a,
.sm-dox>li:first-child>:not(ul) a {
border-radius:5px 5px 0 0
}
.sm-dox>li:last-child>a,
.sm-dox>li:last-child>*:not(ul) a,
.sm-dox>li:last-child>ul,
.sm-dox>li:last-child>ul>li:last-child>a,
.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,
.sm-dox>li:last-child>ul>li:last-child>ul,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul {
border-radius:0 0 5px 5px
}
.sm-dox>li:last-child>a.highlighted,
.sm-dox>li:last-child>*:not(ul) a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,
.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted {
border-radius:0
}
.sm-dox ul {
background:rgba(162,162,162,0.1)
}
.sm-dox ul a,
.sm-dox ul a:focus,
.sm-dox ul a:hover,
.sm-dox ul a:active {
font-size:12px;
border-left:8px solid transparent;
line-height:36px;
text-shadow:none;
background-color:white;
}
.sm-dox ul a:hover {
color:#fff;
}
.sm-dox ul ul a,
.sm-dox ul ul a:hover,
.sm-dox ul ul a:focus,
.sm-dox ul ul a:active {
border-left:16px solid transparent
}
.sm-dox ul ul ul a,
.sm-dox ul ul ul a:hover,
.sm-dox ul ul ul a:focus,
.sm-dox ul ul ul a:active {
border-left:24px solid transparent
}
.sm-dox ul ul ul ul a,
.sm-dox ul ul ul ul a:hover,
.sm-dox ul ul ul ul a:focus,
.sm-dox ul ul ul ul a:active {
border-left:32px solid transparent
}
.sm-dox ul ul ul ul ul a,
.sm-dox ul ul ul ul ul a:hover,
.sm-dox ul ul ul ul ul a:focus,
.sm-dox ul ul ul ul ul a:active {
border-left:40px solid transparent
}
@media (min-width: 768px) {
.sm-dox ul {
position:absolute;
width:12em
}
.sm-dox li {
float:left
}
.sm-dox.sm-rtl li {
float:right
}
.sm-dox ul li,
.sm-dox.sm-rtl ul li,
.sm-dox.sm-vertical li {
float:none
}
.sm-dox a {
white-space:nowrap
}
.sm-dox ul a,
.sm-dox.sm-vertical a {
white-space:normal
}
.sm-dox .sm-nowrap>li>a,
.sm-dox .sm-nowrap>li>:not(ul) a {
white-space:nowrap
}
.sm-dox {
padding:0 10px;
line-height:36px
}
.sm-dox a span.sub-arrow {
top:50%;
margin-top:-2px;
right:12px;
width:0;
height:0;
border-width:4px;
border-style:solid dashed dashed dashed;
border-color:rgba(255,255,255,0.5) transparent transparent transparent;
background:transparent;
border-radius:0
}
.sm-dox a,
.sm-dox a:focus,
.sm-dox a:active,
.sm-dox a:hover,
.sm-dox a.highlighted {
padding:0px 12px;
border-radius:0 !important
}
.sm-dox a:hover {
color:#fff;
}
.sm-dox a:hover span.sub-arrow {
border-color:#fff transparent transparent transparent
}
.sm-dox a.has-submenu {
padding-right:24px
}
.sm-dox li {
border-top:0
}
.sm-dox>li>ul {
top: 36px !important;
}
.sm-dox>li>ul:before,
.sm-dox>li>ul:after {
content:'';
position:absolute;
top:-18px;
left:30px;
width:0;
height:0;
overflow:hidden;
border-width:9px;
border-style:dashed dashed solid dashed;
border-color:transparent transparent #bbb transparent
}
.sm-dox>li>ul:after {
top:-16px;
left:31px;
border-width:8px;
border-color:transparent transparent #fff transparent
}
.sm-dox ul {
border:1px solid #bbb;
padding:5px 0;
background:#fff;
border-radius:5px !important;
}
.sm-dox ul a span.sub-arrow {
right:8px;
top:50%;
margin-top:-5px;
border-width:5px;
border-color:transparent transparent transparent #555;
border-style:dashed dashed dashed solid
}
.sm-dox ul a,
.sm-dox ul a:hover,
.sm-dox ul a:focus,
.sm-dox ul a:active,
.sm-dox ul a.highlighted {
color:#555;
border:0 !important;
}
.sm-dox ul a:hover {
color: #1e2125;
background-color: #f8f9fa;
}
.sm-dox ul a:hover span.sub-arrow {
border-color:transparent transparent transparent #1e2125
}
.sm-dox span.scroll-up,
.sm-dox span.scroll-down {
position:absolute;
display:none;
visibility:hidden;
overflow:hidden;
background:#fff;
height:36px
}
.sm-dox span.scroll-up:hover,
.sm-dox span.scroll-down:hover {
background:#eee
}
.sm-dox span.scroll-up:hover span.scroll-up-arrow,
.sm-dox span.scroll-up:hover span.scroll-down-arrow {
border-color:transparent transparent #D23600 transparent
}
.sm-dox span.scroll-down:hover span.scroll-down-arrow {
border-color:#D23600 transparent transparent transparent
}
.sm-dox span.scroll-up-arrow,
.sm-dox span.scroll-down-arrow {
position:absolute;
top:0;
left:50%;
margin-left:-6px;
width:0;
height:0;
overflow:hidden;
border-width:6px;
border-style:dashed dashed solid dashed;
border-color:transparent transparent #555 transparent
}
.sm-dox span.scroll-down-arrow {
top:8px;
border-style:solid dashed dashed dashed;
border-color:#555 transparent transparent transparent
}
.sm-dox.sm-vertical {
padding:10px 0;
border-radius:5px
}
.sm-dox.sm-vertical a {
padding:10px 20px
}
.sm-dox.sm-vertical a:hover,
.sm-dox.sm-vertical a:focus,
.sm-dox.sm-vertical a:active,
.sm-dox.sm-vertical a.highlighted {
background:#fff
}
.sm-dox.sm-vertical a.disabled {
}
.sm-dox.sm-vertical a span.sub-arrow {
right:8px;
top:50%;
margin-top:-5px;
border-width:5px;
border-style:dashed dashed dashed solid;
border-color:transparent transparent transparent #555
}
.sm-dox.sm-vertical>li>ul:before,
.sm-dox.sm-vertical>li>ul:after {
display:none
}
.sm-dox.sm-vertical ul a {
padding:10px 20px
}
.sm-dox.sm-vertical ul a:hover,
.sm-dox.sm-vertical ul a:focus,
.sm-dox.sm-vertical ul a:active,
.sm-dox.sm-vertical ul a.highlighted {
background:#eee
}
.sm-dox.sm-vertical ul a.disabled {
background:#fff
}
}

View File

@ -1,8 +1,16 @@
'''
Useful collection types not found in the core interpreter.
'''
class defaultdict(dict):
'''
Extended mapping type that automatically populates missing keys with values from a factory.
'''
def __init__(self, default_factory=None, *args, **kwargs):
super().__init__(*args,**kwargs)
self.default_factory = default_factory
def __missing__(self, key):
'''Automatically called to create default values when @p key is not found.'''
if not self.default_factory: raise KeyError(key)
let result = self.default_factory()
self.__set__(key, result)
@ -13,6 +21,9 @@ class defaultdict(dict):
return super().__get__(key)
class deque():
'''
Linked list with fast push/pop/enque/deque operations but slow lookup.
'''
def __init__(self, iterable=None, maxlen=None):
self._head = None
self._tail = None

View File

@ -358,7 +358,7 @@ void _createAndBind_builtins(void) {
krk_defineNative(&vm.baseClasses->moduleClass->methods, ".__repr__", _module_repr);
krk_defineNative(&vm.baseClasses->moduleClass->methods, ".__str__", _module_repr);
krk_finalizeClass(vm.baseClasses->moduleClass);
vm.baseClasses->moduleClass->docstring = S("");
vm.baseClasses->moduleClass->docstring = S("Type of imported modules and packages.");
vm.builtins = krk_newInstance(vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.modules, "__builtins__", (KrkObj*)vm.builtins);

View File

@ -155,55 +155,58 @@ KrkValue krk_module_onload_math(void) {
KrkInstance * module = krk_newInstance(vm.baseClasses->moduleClass);
krk_push(OBJECT_VAL(module));
bind(ceil);
bind(floor);
krk_attachNamedObject(&module->fields, "__doc__",(KrkObj*)
S("Provides access to floating-point mathematical functions from the system `libm`."));
bind(ceil)->doc = "Returns the smallest integer value not less than the input.";
bind(floor)->doc = "Returns the largest integer value not greater than the input.";
#ifdef _math_trunc
bind(trunc);
bind(trunc)->doc = "Rounds the input towards zero to an integer.";
#endif
bind(exp);
bind(exp)->doc = "Returns the base-e exponentiation of the input.";
#ifdef _math_expm1
bind(expm1);
bind(expm1)->doc = "Equivalent to `exp(x) - 1`.";
#endif
bind(log2);
bind(log10);
bind(sqrt);
bind(acos);
bind(asin);
bind(atan);
bind(cos);
bind(sin);
bind(tan);
bind(log2)->doc = "Calculates the base-2 logarithm of the input.";
bind(log10)->doc = "Calculates the base-10 logarithm of the input.";
bind(sqrt)->doc = "Calculates the square root of the input.";
bind(acos)->doc = "Calculates the arc-cosine of the radian input.";
bind(asin)->doc = "Calculates the arc-sine of the radian input.";
bind(atan)->doc = "Calculates the arc-tangent of the radian input.";
bind(cos)->doc = "Calculates the cosine of the radian input.";
bind(sin)->doc = "Calculates the sine of the radian input.";
bind(tan)->doc = "Calculates the tangent of the radian input.";
#ifdef _math_acosh
bind(acosh);
bind(asinh);
bind(atanh);
bind(acosh)->doc = "Calculates the inverse hyperbolic cosine of the input.";
bind(asinh)->doc = "Calculates the inverse hyperbolic sine of the input.";
bind(atanh)->doc = "Calculates the inverse hyperbolic tangent of the input.";
#endif
bind(cosh);
bind(sinh);
bind(tanh);
bind(cosh)->doc = "Calculates the hyperbolic cosine of the input.";
bind(sinh)->doc = "Calculates the hyperbolic sine of the input.";
bind(tanh)->doc = "Calculates the hyperbolic tangent of the input.";
#ifdef _math_erf
bind(erf);
bind(erfc);
bind(erf)->doc = "Calculates the error function of the input.";
bind(erfc)->doc = "Calculates the complementary error function of the input.";
#endif
#ifdef _math_gamma
bind(gamma);
bind(lgamma);
bind(gamma)->doc = "Calculates the gamma of the input.";
bind(lgamma)->doc = "Calculates the log gamma of the input.";
#endif
#ifdef _math_copysign
bind(copysign);
bind(copysign)->doc = "Copies the sign from one value to another.";
#endif
bind(fmod);
bind(fmod)->doc = "Returns the floating point remainder of the first input over the second.";
#ifdef _math_remainder
bind(remainder);
bind(remainder)->doc = "Somehow different from `fmod`.";
#endif
bind(log1p);
bind(pow);
bind(atan2);
bind(frexp);
bind(log1p)->doc = "Equivalent to `log(x) + 1`";
bind(pow)->doc = "Calculates `x^p`";
bind(atan2)->doc = "Calculates the arctangent of `x` and `y`";
bind(frexp)->doc = "Converts a floating point input to a fractional and integer component pair, returned as a tuple.";
#ifdef isfinite
bind(isfinite);
bind(isinf);
bind(isnan);
bind(isfinite)->doc = "Determines if the input is finite.";
bind(isinf)->doc = "Determines if the input is infinite.";
bind(isnan)->doc = "Determines if the input is the floating point `NaN`.";
#endif
/**

View File

@ -1220,14 +1220,29 @@ void krk_initVM(int flags) {
krk_attachNamedObject(&vm.modules, "kuroko", (KrkObj*)vm.system);
krk_attachNamedObject(&vm.system->fields, "__name__", (KrkObj*)S("kuroko"));
krk_attachNamedValue(&vm.system->fields, "__file__", NONE_VAL()); /* (built-in) */
krk_attachNamedObject(&vm.system->fields, "__doc__", (KrkObj*)S("System module."));
krk_attachNamedObject(&vm.system->fields, "version",
(KrkObj*)S(KRK_VERSION_MAJOR "." KRK_VERSION_MINOR "." KRK_VERSION_PATCH KRK_VERSION_EXTRA));
krk_attachNamedObject(&vm.system->fields, "buildenv", (KrkObj*)S(KRK_BUILD_COMPILER));
krk_attachNamedObject(&vm.system->fields, "builddate", (KrkObj*)S(KRK_BUILD_DATE));
krk_defineNative(&vm.system->fields, "getsizeof", krk_getsize);
krk_defineNative(&vm.system->fields, "set_clean_output", krk_setclean);
krk_defineNative(&vm.system->fields, "set_tracing", krk_set_tracing)->doc = "Toggle debugging modes.";
krk_defineNative(&vm.system->fields, "importmodule", krk_import_wrapper)->doc = "Import a module by string name";
krk_defineNative(&vm.system->fields, "getsizeof", krk_getsize)->doc = "Calculate the approximate size of an object in bytes.\n"
"@arguments value\n\n"
"@param value Value to examine.";
krk_defineNative(&vm.system->fields, "set_clean_output", krk_setclean)->doc = "Disables terminal escapes in some output from the VM.\n"
"@arguments clean=True\n\n"
"@param clean Whether to remove escapes.";
krk_defineNative(&vm.system->fields, "set_tracing", krk_set_tracing)->doc = "Toggle debugging modes.\n"
"@arguments tracing=None,disassembly=None,scantracing=None,stressgc=None\n\n"
"Enables or disables tracing options for the current thread.\n\n"
"@param tracing Enables instruction tracing.\n"
"@param disassembly Prints bytecode disassembly after compilation.\n"
"@param scantracing Prints debug output from the token scanner during compilation.\n"
"@param stressgc Forces a garbage collection cycle on each heap allocation.";
krk_defineNative(&vm.system->fields, "importmodule", krk_import_wrapper)->doc = "Import a module by string name\n"
"@arguments module\n\n"
"Imports the dot-separated module @p module as if it were imported by the @c import statement and returns the resulting module object.\n\n"
"@param module A string with a dot-separated package or module name";
krk_attachNamedObject(&vm.system->fields, "module", (KrkObj*)vm.baseClasses->moduleClass);
krk_attachNamedObject(&vm.system->fields, "path_sep", (KrkObj*)S(PATH_SEP));
KrkValue module_paths = krk_list_of(0,NULL,0);
krk_attachNamedValue(&vm.system->fields, "module_paths", module_paths);

1
tools/__init__.krk Normal file
View File

@ -0,0 +1 @@

263
tools/gendoc.krk Executable file
View File

@ -0,0 +1,263 @@
#!/usr/bin/env kuroko
'''
@brief Tool for dynamically generating documentation files through introspection.
Imports modules and scans through members to generate Markdown files to feed into
Doxygen. Uses dynamic introspection to obtain member lists and look up function
arguments, docstrings, etc.
Markdown output is aided by a set of macros defined in the Kuroko API Documentation
Doxyfile. The output should be suitable for use with a normal Doxygen build, but some
additional customization is available.
'''
import fileio
import kuroko
import syntax.highlighter
let realPrint = print
let blacklistedMethods = [
'__func__',
'__repr__',
'__str__',
]
let specialMethods = {
'__contains__': lambda cls, args: f'{args} in {cls}',
'__init__': lambda cls, args: f'{cls}({args})',
'__get__': lambda cls, args: f'{cls}[{args}]',
}
class Pair():
'''Makes a silly sortable pair that can be expanded like a two-tuple.'''
def __init__(left,right):
self.left = left
self.right = right
def __lt__(other):
if self.left == '__init__': return True
return self.left < other.left
def __gt__(other):
if self.left == '__init__': return False
return self.left > other.left
def __iter__():
let x = -1
def _():
x++
if x == 0: return self.left
elif x == 1: return self.right
else: return _
return _
let modules = [
# Integrated stuff
'__builtins__',
'os',
'kuroko',
'math',
'threading',
'gc',
'dis',
'fileio',
'time',
# Stuff from modules/
'json',
'collections',
'string',
# Other stuff
'tools.gendoc',
]
let docString = {}
def fixup(mod):
if mod.startswith('__'): return '\\' + mod
return mod
def truncateString(s):
s = s.strip()
if '\n' in s:
s = s.split('\n')[0]
let short = s[:100]
if len(short) < len(s):
return short + '...'
else:
return short
def fixupDoc(doc):
for line in doc.split('\n'):
if line.strip().startswith('@brief '):
doc = line.strip().replace('@brief ', '', 1).strip()
realPrint('derp:',doc)
break
return doc.replace(',','\\,').replace('<','&lt;').replace('>','&gt;')
def isExceptionType(cls):
if cls == Exception: return True
let checked = []
while '__base__' in dir(cls) and cls.__base__ not in checked:
if cls.__base__ == Exception: return True
checked.append(cls.__base__)
cls = cls.__base__
return False
def getArgs(func):
if func.__file__ == '<builtin>':
if '__doc__' in dir(func) and func.__doc__ and '@arguments ' in func.__doc__:
let before, after = func.__doc__.split('@arguments ',1)
let line, rest = after.split('\n',1) if '\n' in after else (after,None)
return line.strip().replace(',','\\,')
return '...'
return '\\,'.join([x for x in func.__args__ if x != 'self'])
def functionDoc(func):
let doc = func.__doc__ if ('__doc__' in dir(func) and func.__doc__) else ''
if '@arguments ' in doc:
doc = '\n'.join([x for x in doc.split('\n') if '@arguments' not in x])
return doc
def processModules(modules):
for modulepath in modules:
# Import the module.
let module = kuroko.importmodule(modulepath)
let output = fileio.open(f'docs/mod.{modulepath}.md','w')
realPrint(f"Processing {modulepath}")
def print(*args):
output.write(' '.join(args))
output.write('\n')
print('## ' + fixup(modulepath) + ' {#mod_' + modulepath.replace('.','_') + '}')
if '__doc__' in dir(module) and module.__doc__:
print(module.__doc__.strip())
docString[modulepath] = truncateString(module.__doc__)
else:
docString[modulepath] = 'TODO'
def outputFunction(name, func, prefix=None):
# Build the function signature
let args = '<i>' + getArgs(func) + '</i>'
let body = functionDoc(func)
let formatted
let maybePrefix = prefix + '.' if prefix else ''
if prefix and name in specialMethods:
formatted = specialMethods[name](prefix,args)
else:
formatted = maybePrefix + '<b>' + name + '</b>(' + args + ')'
print('\\methodstart{' + maybePrefix + name + ',' + formatted + ',' + ('h4,methodDef' if prefix else 'h3,functionDef') + '}')
if body: print(body)
print('\n\\methodend')
print('')
def outputConstant(name, val):
print(f'<h3 class=\"letDef\"><i>let</i> <b>{name}</b> = <code>\htmlonly {val!r} \\endhtmlonly</code></h3>\n')
def outputOther(name, val):
print(f'<h3 class=\"letDef\"><i>let</i> <b>{name}</b> = <i>{type(val).__name__}</i></h3>\n')
def outputClass(name, cls):
let classType = 'exceptionDef' if isExceptionType(cls) else 'classDef'
let superclass = cls.__base__.__name__ if cls.__base__ else ''
let formatted = f'<i>class</i> <b>{name}</b>({superclass})'
print('\\methodstart{' + name + ',' + formatted + ',h3,' + classType + '}')
if '__doc__' in dir(cls) and isinstance(cls.__doc__,str):
print('<p>' + cls.__doc__ + '</p>')
let seen = []
let methods = []
for member in dir(cls):
if member in blacklistedMethods: continue
realPrint(cls,member)
let obj
try:
obj = getattr(cls,member)
if cls.__base__ and member in dir(cls.__base__) and getattr(cls.__base__,member) == obj: continue
except:
continue
if isinstance(obj, function) and member not in seen:
seen.append(member)
methods.append(Pair(member,obj))
if methods:
methods.sort()
for methodName, method in methods:
outputFunction(methodName, method, prefix=name)
print('\\methodend')
def dumpModule(name, thing):
let functions = []
let classes = []
let constants = []
let exceptions = []
let other = []
for member in dir(thing):
if not member.startswith('_'):
let obj = getattr(thing,member)
if isinstance(obj, function):
functions.append(Pair(member,obj))
else if isinstance(obj, type):
if isExceptionType(obj):
exceptions.append(Pair(member,obj))
else:
classes.append(Pair(member,obj))
else if isinstance(obj, (int,str,float,bool,type(None))):
constants.append(Pair(member,obj))
else if isinstance(obj, kuroko.module):
continue # Skip top-level modules as these are almost definitely imports
else:
other.append(Pair(member,obj))
if classes:
print('\n### Classes\n')
classes.sort()
for name, cls in classes:
outputClass(name, cls)
if functions:
print('\n### Functions\n')
functions.sort()
for name, func in functions:
outputFunction(name, func)
if exceptions:
print('\n### Exceptions\n')
exceptions.sort()
for name, cls in exceptions:
outputClass(name, cls)
if constants:
print('\n### Constants\n')
constants.sort()
for name, val in constants:
outputConstant(name,val)
if other:
print('\n### Other Members\n')
other.sort()
for name, val in other:
outputOther(name, val)
dumpModule(modulepath,module)
output.close()
with fileio.open('docs/modulelist.md','w') as output:
output.write(
'# Module List {#modulelist}\n'
'\n'
'Here is a list of documented modules:\n'
'\n'
'\\modulelist{\n'
)
modules.sort()
for module in modules:
output.write(' \\krkmodule{mod_' + fixup(module).replace('.','_') + ',' + fixupDoc(docString[module]) + '}\n')
output.write('}\n')
if __name__ == '__main__':
processModules(modules)