Allow for entity grouping in structs and procedure signatures with the Odin doc-format

This commit is contained in:
gingerBill
2022-01-19 14:57:27 +00:00
parent 6bdb210ad8
commit 28a816ef25
7 changed files with 119 additions and 59 deletions
+5 -1
View File
@@ -11,7 +11,7 @@ String :: distinct Array(byte)
Version_Type_Major :: 0 Version_Type_Major :: 0
Version_Type_Minor :: 2 Version_Type_Minor :: 2
Version_Type_Patch :: 2 Version_Type_Patch :: 3
Version_Type :: struct { Version_Type :: struct {
major, minor, patch: u8, major, minor, patch: u8,
@@ -122,6 +122,10 @@ Entity :: struct {
_: u32le, // reserved for init _: u32le, // reserved for init
comment: String, comment: String,
docs: String, docs: String,
// May be used by (Struct fields and procedure fields):
// .Variable
// .Constant
field_group_index: i32le,
// May used by: // May used by:
// .Variable // .Variable
+13
View File
@@ -109,11 +109,14 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
} }
i32 field_src_index = 0; i32 field_src_index = 0;
i32 field_group_index = -1;
for_array(i, params) { for_array(i, params) {
Ast *param = params[i]; Ast *param = params[i];
if (param->kind != Ast_Field) { if (param->kind != Ast_Field) {
continue; continue;
} }
field_group_index += 1;
ast_node(p, Field, param); ast_node(p, Field, param);
Ast *type_expr = p->type; Ast *type_expr = p->type;
Type *type = nullptr; Type *type = nullptr;
@@ -152,6 +155,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index); Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
add_entity(ctx, ctx->scope, name, field); add_entity(ctx, ctx->scope, name, field);
field->Variable.field_group_index = field_group_index;
array_add(&fields_array, field); array_add(&fields_array, field);
String tag = p->tag.string; String tag = p->tag.string;
if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) { if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) {
@@ -1366,11 +1370,13 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
isize variadic_index = -1; isize variadic_index = -1;
bool is_c_vararg = false; bool is_c_vararg = false;
auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count); auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count);
i32 field_group_index = -1;
for_array(i, params) { for_array(i, params) {
Ast *param = params[i]; Ast *param = params[i];
if (param->kind != Ast_Field) { if (param->kind != Ast_Field) {
continue; continue;
} }
field_group_index += 1;
ast_node(p, Field, param); ast_node(p, Field, param);
Ast *type_expr = unparen_expr(p->type); Ast *type_expr = unparen_expr(p->type);
Type *type = nullptr; Type *type = nullptr;
@@ -1671,9 +1677,11 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
} }
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type)); param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
param->Constant.field_group_index = field_group_index;
} else { } else {
param = alloc_entity_param(scope, name->Ident.token, type, is_using, true); param = alloc_entity_param(scope, name->Ident.token, type, is_using, true);
param->Variable.param_value = param_value; param->Variable.param_value = param_value;
param->Variable.field_group_index = field_group_index;
} }
} }
if (p->flags&FieldFlag_no_alias) { if (p->flags&FieldFlag_no_alias) {
@@ -1767,7 +1775,10 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
} }
auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count); auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count);
i32 field_group_index = -1;
for_array(i, results) { for_array(i, results) {
field_group_index += 1;
ast_node(field, Field, results[i]); ast_node(field, Field, results[i]);
Ast *default_value = unparen_expr(field->default_value); Ast *default_value = unparen_expr(field->default_value);
ParameterValue param_value = {}; ParameterValue param_value = {};
@@ -1798,6 +1809,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
token.string = str_lit(""); token.string = str_lit("");
Entity *param = alloc_entity_param(scope, token, type, false, false); Entity *param = alloc_entity_param(scope, token, type, false, false);
param->Variable.param_value = param_value; param->Variable.param_value = param_value;
param->Variable.field_group_index = -1;
array_add(&variables, param); array_add(&variables, param);
} else { } else {
for_array(j, field->names) { for_array(j, field->names) {
@@ -1821,6 +1833,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
Entity *param = alloc_entity_param(scope, token, type, false, false); Entity *param = alloc_entity_param(scope, token, type, false, false);
param->flags |= EntityFlag_Result; param->flags |= EntityFlag_Result;
param->Variable.param_value = param_value; param->Variable.param_value = param_value;
param->Variable.field_group_index = field_group_index;
array_add(&variables, param); array_add(&variables, param);
add_entity(ctx, scope, name, param); add_entity(ctx, scope, name, param);
// NOTE(bill): Removes `declared but not used` when using -vet // NOTE(bill): Removes `declared but not used` when using -vet
+2 -1
View File
@@ -15,7 +15,7 @@ struct OdinDocVersionType {
#define OdinDocVersionType_Major 0 #define OdinDocVersionType_Major 0
#define OdinDocVersionType_Minor 2 #define OdinDocVersionType_Minor 2
#define OdinDocVersionType_Patch 2 #define OdinDocVersionType_Patch 3
struct OdinDocHeaderBase { struct OdinDocHeaderBase {
u8 magic[8]; u8 magic[8];
@@ -185,6 +185,7 @@ struct OdinDocEntity {
u32 reserved_for_init; u32 reserved_for_init;
OdinDocString comment; OdinDocString comment;
OdinDocString docs; OdinDocString docs;
i32 field_group_index;
OdinDocEntityIndex foreign_library; OdinDocEntityIndex foreign_library;
OdinDocString link_name; OdinDocString link_name;
OdinDocArray<OdinDocAttribute> attributes; OdinDocArray<OdinDocAttribute> attributes;
+16 -4
View File
@@ -512,10 +512,16 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
doc_type.entities = odin_doc_add_entity_as_slice(w, type->Named.type_name); doc_type.entities = odin_doc_add_entity_as_slice(w, type->Named.type_name);
break; break;
case Type_Generic: case Type_Generic:
doc_type.kind = OdinDocType_Generic; {
doc_type.name = odin_doc_write_string(w, type->Generic.entity->token.string); String name = type->Generic.name;
if (type->Generic.specialized) { if (type->Generic.entity) {
doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); name = type->Generic.entity->token.string;
}
doc_type.kind = OdinDocType_Generic;
doc_type.name = odin_doc_write_string(w, name);
if (type->Generic.specialized) {
doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized);
}
} }
break; break;
case Type_Pointer: case Type_Pointer:
@@ -810,6 +816,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
OdinDocEntityKind kind = OdinDocEntity_Invalid; OdinDocEntityKind kind = OdinDocEntity_Invalid;
u32 flags = 0; u32 flags = 0;
i32 field_group_index = -1;
switch (e->kind) { switch (e->kind) {
case Entity_Invalid: kind = OdinDocEntity_Invalid; break; case Entity_Invalid: kind = OdinDocEntity_Invalid; break;
@@ -839,6 +846,10 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
if (init_expr == nullptr) { if (init_expr == nullptr) {
init_expr = e->Variable.init_expr; init_expr = e->Variable.init_expr;
} }
field_group_index = e->Variable.field_group_index;
break;
case Entity_Constant:
field_group_index = e->Constant.field_group_index;
break; break;
case Entity_Procedure: case Entity_Procedure:
if (e->Procedure.is_foreign) { flags |= OdinDocEntityFlag_Foreign; } if (e->Procedure.is_foreign) { flags |= OdinDocEntityFlag_Foreign; }
@@ -883,6 +894,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
doc_entity.init_string = init_string; doc_entity.init_string = init_string;
doc_entity.comment = odin_doc_comment_group_string(w, comment); doc_entity.comment = odin_doc_comment_group_string(w, comment);
doc_entity.docs = odin_doc_comment_group_string(w, docs); doc_entity.docs = odin_doc_comment_group_string(w, docs);
doc_entity.field_group_index = field_group_index;
doc_entity.foreign_library = 0; // Set later doc_entity.foreign_library = 0; // Set later
doc_entity.link_name = odin_doc_write_string(w, link_name); doc_entity.link_name = odin_doc_write_string(w, link_name);
if (e->decl_info != nullptr) { if (e->decl_info != nullptr) {
+2
View File
@@ -160,10 +160,12 @@ struct Entity {
ExactValue value; ExactValue value;
ParameterValue param_value; ParameterValue param_value;
u32 flags; u32 flags;
i32 field_group_index;
} Constant; } Constant;
struct { struct {
Ast *init_expr; // only used for some variables within procedure bodies Ast *init_expr; // only used for some variables within procedure bodies
i32 field_index; i32 field_index;
i32 field_group_index;
ParameterValue param_value; ParameterValue param_value;
+69 -52
View File
@@ -10,6 +10,7 @@ import "core:sort"
import "core:slice" import "core:slice"
GITHUB_CORE_URL :: "https://github.com/odin-lang/Odin/tree/master/core" GITHUB_CORE_URL :: "https://github.com/odin-lang/Odin/tree/master/core"
BASE_CORE_URL :: "/core"
header: ^doc.Header header: ^doc.Header
files: []doc.File files: []doc.File
@@ -96,7 +97,7 @@ write_html_footer :: proc(w: io.Writer, include_directory_js: bool) {
io.write(w, #load("footer.txt.html")) io.write(w, #load("footer.txt.html"))
if include_directory_js { if false && include_directory_js {
io.write_string(w, ` io.write_string(w, `
<script type="text/javascript"> <script type="text/javascript">
(function (win, doc) { (function (win, doc) {
@@ -319,7 +320,7 @@ write_core_directory :: proc(w: io.Writer) {
} }
if dir.pkg != nil { if dir.pkg != nil {
fmt.wprintf(w, `<a href="/core/%s">%s</a>`, dir.path, dir.name) fmt.wprintf(w, `<a href="%s/%s">%s</a>`, BASE_CORE_URL, dir.path, dir.name)
} else { } else {
fmt.wprintf(w, "%s", dir.name) fmt.wprintf(w, "%s", dir.name)
} }
@@ -338,7 +339,7 @@ write_core_directory :: proc(w: io.Writer) {
for child := dir.first_child; child != nil; child = child.next { for child := dir.first_child; child != nil; child = child.next {
assert(child.pkg != nil) assert(child.pkg != nil)
fmt.wprintf(w, `<tr id="pkg-%s" class="directory-pkg directory-child"><td class="pkg-line pkg-name">`, str(child.pkg.name)) fmt.wprintf(w, `<tr id="pkg-%s" class="directory-pkg directory-child"><td class="pkg-line pkg-name">`, str(child.pkg.name))
fmt.wprintf(w, `<a href="/core/%s/">%s</a>`, child.path, child.name) fmt.wprintf(w, `<a href="%s/%s/">%s</a>`, BASE_CORE_URL, child.path, child.name)
io.write_string(w, `</td>`) io.write_string(w, `</td>`)
line_doc, _, _ := strings.partition(str(child.pkg.docs), "\n") line_doc, _, _ := strings.partition(str(child.pkg.docs), "\n")
@@ -392,7 +393,7 @@ Type_Writer :: struct {
} }
write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type_Flags) { write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type_Flags) {
write_param_entity :: proc(using writer: ^Type_Writer, e: ^doc.Entity, flags: Write_Type_Flags, name_width := 0) { write_param_entity :: proc(using writer: ^Type_Writer, e, next_entity: ^doc.Entity, flags: Write_Type_Flags, name_width := 0) {
name := str(e.name) name := str(e.name)
write_padding :: proc(w: io.Writer, name: string, name_width: int) { write_padding :: proc(w: io.Writer, name: string, name_width: int) {
@@ -414,13 +415,13 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
assert(name != "") assert(name != "")
io.write_string(w, name) io.write_string(w, name)
io.write_string(w, " := ") io.write_string(w, " := ")
io.write_string(w, `<a href="/core/runtime/#Source_Code_Location">`) fmt.wprintf(w, `<a href="%s/runtime/#Source_Code_Location">`, BASE_CORE_URL)
io.write_string(w, init_string) io.write_string(w, init_string)
io.write_string(w, `</a>`) io.write_string(w, `</a>`)
case strings.has_prefix(init_string, "context."): case strings.has_prefix(init_string, "context."):
io.write_string(w, name) io.write_string(w, name)
io.write_string(w, " := ") io.write_string(w, " := ")
io.write_string(w, `<a href="/core/runtime/#Context">`) fmt.wprintf(w, `<a href="%s/runtime/#Context">`, BASE_CORE_URL)
io.write_string(w, init_string) io.write_string(w, init_string)
io.write_string(w, `</a>`) io.write_string(w, `</a>`)
case: case:
@@ -435,6 +436,12 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
assert(name != "") assert(name != "")
io.write_byte(w, '$') io.write_byte(w, '$')
io.write_string(w, name) io.write_string(w, name)
if name != "" && init_string == "" && next_entity != nil && e.field_group_index >= 0 {
if e.field_group_index == next_entity.field_group_index && e.type == next_entity.type {
return
}
}
generic_scope[name] = true generic_scope[name] = true
if !is_type_untyped(the_type) { if !is_type_untyped(the_type) {
io.write_string(w, ": ") io.write_string(w, ": ")
@@ -449,6 +456,13 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
return return
case .Variable: case .Variable:
if name != "" && init_string == "" && next_entity != nil && e.field_group_index >= 0 {
if e.field_group_index == next_entity.field_group_index && e.type == next_entity.type {
io.write_string(w, name)
return
}
}
if name != "" { if name != "" {
io.write_string(w, name) io.write_string(w, name)
io.write_string(w, ": ") io.write_string(w, ": ")
@@ -530,10 +544,10 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
fmt.wprintf(w, `%s.`, str(pkgs[tn_pkg].name)) fmt.wprintf(w, `%s.`, str(pkgs[tn_pkg].name))
} }
if n := strings.contains_rune(name, '('); n >= 0 { if n := strings.contains_rune(name, '('); n >= 0 {
fmt.wprintf(w, `<a class="code-typename" href="/core/{0:s}/#{1:s}">{1:s}</a>`, pkg_to_path[&pkgs[tn_pkg]], name[:n]) fmt.wprintf(w, `<a class="code-typename" href="{2:s}/{0:s}/#{1:s}">{1:s}</a>`, pkg_to_path[&pkgs[tn_pkg]], name[:n], BASE_CORE_URL)
io.write_string(w, name[n:]) io.write_string(w, name[n:])
} else { } else {
fmt.wprintf(w, `<a class="code-typename" href="/core/{0:s}/#{1:s}">{1:s}</a>`, pkg_to_path[&pkgs[tn_pkg]], name) fmt.wprintf(w, `<a class="code-typename" href="{2:s}/{0:s}/#{1:s}">{1:s}</a>`, pkg_to_path[&pkgs[tn_pkg]], name, BASE_CORE_URL)
} }
case .Generic: case .Generic:
name := str(type.name) name := str(type.name)
@@ -590,10 +604,14 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
indent += 1 indent += 1
name_width := calc_name_width(type_entites) name_width := calc_name_width(type_entites)
for entity_index in type_entites { for entity_index, i in type_entites {
e := &entities[entity_index] e := &entities[entity_index]
next_entity: ^doc.Entity = nil
if i+1 < len(type_entites) {
next_entity = &entities[type_entites[i+1]]
}
do_indent(writer, flags) do_indent(writer, flags)
write_param_entity(writer, e, flags, name_width) write_param_entity(writer, e, next_entity, flags, name_width)
io.write_byte(w, ',') io.write_byte(w, ',')
do_newline(writer, flags) do_newline(writer, flags)
} }
@@ -667,7 +685,12 @@ write_type :: proc(using writer: ^Type_Writer, type: doc.Type, flags: Write_Type
if i > 0 { if i > 0 {
io.write_string(w, ", ") io.write_string(w, ", ")
} }
write_param_entity(writer, &entities[entity_index], flags) e := &entities[entity_index]
next_entity: ^doc.Entity = nil
if i+1 < len(type_entites) {
next_entity = &entities[type_entites[i+1]]
}
write_param_entity(writer, e, next_entity, flags)
} }
if require_parens { io.write_byte(w, ')') } if require_parens { io.write_byte(w, ')') }
@@ -821,7 +844,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintln(w, `<div class="row odin-main">`) fmt.wprintln(w, `<div class="row odin-main">`)
defer fmt.wprintln(w, `</div>`) defer fmt.wprintln(w, `</div>`)
fmt.wprintln(w, `<article class="col-lg-9 p-4">`) fmt.wprintln(w, `<article class="col-lg-9 p-4 documentation">`)
{ // breadcrumbs { // breadcrumbs
fmt.wprintln(w, `<div class="row">`) fmt.wprintln(w, `<div class="row">`)
@@ -832,7 +855,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
io.write_string(w, "<ol class=\"breadcrumb\">\n") io.write_string(w, "<ol class=\"breadcrumb\">\n")
defer io.write_string(w, "</ol>\n") defer io.write_string(w, "</ol>\n")
io.write_string(w, `<li class="breadcrumb-item"><a class="breadcrumb-link" href="/core">core</a></li>`) fmt.wprintf(w, `<li class="breadcrumb-item"><a class="breadcrumb-link" href="%s">core</a></li>`, BASE_CORE_URL)
dirs := strings.split(path, "/") dirs := strings.split(path, "/")
for dir, i in dirs { for dir, i in dirs {
@@ -848,7 +871,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
} }
if !is_curr && short_path in pkgs_to_use { if !is_curr && short_path in pkgs_to_use {
fmt.wprintf(w, `<a href="/core/%s">%s</a>`, url, dir) fmt.wprintf(w, `<a href="%s/%s">%s</a>`, BASE_CORE_URL, url, dir)
} else { } else {
io.write_string(w, dir) io.write_string(w, dir)
} }
@@ -858,19 +881,18 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintf(w, "<h1>package core:%s</h1>\n", path) fmt.wprintf(w, "<h1>package core:%s</h1>\n", path)
fmt.wprintln(w, "<h2>Documentation</h2>")
overview_docs := strings.trim_space(str(pkg.docs)) overview_docs := strings.trim_space(str(pkg.docs))
if overview_docs != "" { if overview_docs != "" {
fmt.wprintln(w, "<h3>Overview</h3>") fmt.wprintln(w, "<h2>Overview</h2>")
fmt.wprintln(w, "<div id=\"pkg-overview\">") fmt.wprintln(w, "<div id=\"pkg-overview\">")
defer fmt.wprintln(w, "</div>") defer fmt.wprintln(w, "</div>")
write_docs(w, pkg, overview_docs) write_docs(w, pkg, overview_docs)
} }
fmt.wprintln(w, `<h3>Index</h3>`) fmt.wprintln(w, `<h2>Index</h2>`)
fmt.wprintln(w, `<section class="doc-index" id="pkg-index">`) fmt.wprintln(w, `<section class="doc-index" id="pkg-index">`)
// fmt.wprintln(w, `<a class="btn btn-primary" data-bs-toggle="collapse" href="#pkg-index" role="button" aria-expanded="true" aria-controls="pkg-index"><h3>Index</h3></a>`) // fmt.wprintln(w, `<a class="btn btn-primary" data-bs-toggle="collapse" href="#pkg-index" role="button" aria-expanded="true" aria-controls="pkg-index"><h2>Index</h2></a>`)
// fmt.wprintln(w, `<section class="doc-index collapse" id="pkg-index">`) // fmt.wprintln(w, `<section class="doc-index collapse" id="pkg-index">`)
pkg_procs: [dynamic]^doc.Entity pkg_procs: [dynamic]^doc.Entity
pkg_proc_groups: [dynamic]^doc.Entity pkg_proc_groups: [dynamic]^doc.Entity
@@ -906,7 +928,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
slice.sort_by_key(pkg_consts[:], entity_key) slice.sort_by_key(pkg_consts[:], entity_key)
write_index :: proc(w: io.Writer, name: string, entities: []^doc.Entity) { write_index :: proc(w: io.Writer, name: string, entities: []^doc.Entity) {
fmt.wprintf(w, "<h4>%s</h4>\n", name) fmt.wprintf(w, "<h3>%s</h3>\n", name)
fmt.wprintln(w, `<section class="doc-index">`) fmt.wprintln(w, `<section class="doc-index">`)
if len(entities) == 0 { if len(entities) == 0 {
io.write_string(w, "<p>This section is empty.</p>\n") io.write_string(w, "<p>This section is empty.</p>\n")
@@ -921,12 +943,18 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintln(w, "</section>") fmt.wprintln(w, "</section>")
} }
entity_ordering := [?]struct{name: string, entities: []^doc.Entity} {
{"Types", pkg_types[:]},
{"Constants", pkg_consts[:]},
{"Variables", pkg_vars[:]},
{"Procedures", pkg_procs[:]},
{"Procedure Groups", pkg_proc_groups[:]},
}
write_index(w, "Procedures", pkg_procs[:])
write_index(w, "Procedure Groups", pkg_proc_groups[:]) for eo in entity_ordering {
write_index(w, "Types", pkg_types[:]) write_index(w, eo.name, eo.entities)
write_index(w, "Variables", pkg_vars[:]) }
write_index(w, "Constants", pkg_consts[:])
fmt.wprintln(w, "</section>") fmt.wprintln(w, "</section>")
@@ -957,13 +985,13 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
name := str(e.name) name := str(e.name)
path := pkg_to_path[pkg] path := pkg_to_path[pkg]
filename := slashpath.base(str(files[e.pos.file].name)) filename := slashpath.base(str(files[e.pos.file].name))
fmt.wprintf(w, "<h4 id=\"{0:s}\"><span><a class=\"doc-id-link\" href=\"#{0:s}\">{0:s}", name) fmt.wprintf(w, "<h3 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>") fmt.wprintf(w, "<span class=\"a-hidden\">&nbsp;¶</span></a></span>")
if e.pos.file != 0 && e.pos.line > 0 { 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) src_url := fmt.tprintf("%s/%s/%s#L%d", GITHUB_CORE_URL, path, filename, e.pos.line)
fmt.wprintf(w, "<div class=\"doc-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") fmt.wprintf(w, "</h3>\n")
switch e.kind { switch e.kind {
case .Invalid, .Import_Name, .Library_Name: case .Invalid, .Import_Name, .Library_Name:
@@ -1045,7 +1073,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintf(w, "%s.", str(pkgs[this_pkg].name)) fmt.wprintf(w, "%s.", str(pkgs[this_pkg].name))
} }
name := str(this_proc.name) name := str(this_proc.name)
fmt.wprintf(w, `<a class="code-procedure" href="/core/{0:s}/#{1:s}">`, pkg_to_path[&pkgs[this_pkg]], name) fmt.wprintf(w, `<a class="code-procedure" href="{2:s}/{0:s}/#{1:s}">`, pkg_to_path[&pkgs[this_pkg]], name, BASE_CORE_URL)
io.write_string(w, name) io.write_string(w, name)
io.write_string(w, `</a>`) io.write_string(w, `</a>`)
io.write_byte(w, ',') io.write_byte(w, ',')
@@ -1059,7 +1087,7 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
write_docs(w, pkg, strings.trim_space(str(e.docs))) write_docs(w, pkg, strings.trim_space(str(e.docs)))
} }
write_entities :: proc(w: io.Writer, title: string, entities: []^doc.Entity) { write_entities :: proc(w: io.Writer, title: string, entities: []^doc.Entity) {
fmt.wprintf(w, "<h3 id=\"pkg-{0:s}\">{0:s}</h3>\n", title) fmt.wprintf(w, "<h2 id=\"pkg-{0:s}\">{0:s}</h2>\n", title)
fmt.wprintln(w, `<section class="documentation">`) fmt.wprintln(w, `<section class="documentation">`)
if len(entities) == 0 { if len(entities) == 0 {
io.write_string(w, "<p>This section is empty.</p>\n") io.write_string(w, "<p>This section is empty.</p>\n")
@@ -1071,14 +1099,11 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintln(w, "</section>") fmt.wprintln(w, "</section>")
} }
write_entities(w, "Procedures", pkg_procs[:]) for eo in entity_ordering {
write_entities(w, "Procedure Groups", pkg_proc_groups[:]) write_entities(w, eo.name, eo.entities)
write_entities(w, "Types", pkg_types[:]) }
write_entities(w, "Variables", pkg_vars[:])
write_entities(w, "Constants", pkg_consts[:])
fmt.wprintln(w, `<h2 id="pkg-source-files">Source Files</h2>`)
fmt.wprintln(w, `<h3 id="pkg-source-files">Source Files</h3>`)
fmt.wprintln(w, "<ul>") fmt.wprintln(w, "<ul>")
any_hidden := false any_hidden := false
source_file_loop: for file_index in array(pkg.files) { source_file_loop: for file_index in array(pkg.files) {
@@ -1118,29 +1143,21 @@ write_pkg :: proc(w: io.Writer, path: string, pkg: ^doc.Pkg) {
fmt.wprintf(w, `<li><a href="#%s">%s</a>`, id, text) 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-3 odin-toc-border navbar-light"><div class="sticky-top odin-below-navbar py-3">`) fmt.wprintln(w, `<div class="col-lg-3 odin-toc-border navbar-light"><div class="sticky-top odin-below-navbar py-3">`)
fmt.wprintln(w, `<nav id="TableOfContents">`) fmt.wprintln(w, `<nav id="TableOfContents">`)
fmt.wprintln(w, `<ul>`) fmt.wprintln(w, `<ul>`)
if overview_docs != "" { if overview_docs != "" {
write_link(w, "pkg-overview", "Overview") write_link(w, "pkg-overview", "Overview")
} }
write_index(w, "Procedures", pkg_procs[:]) for eo in entity_ordering do if len(eo.entities) != 0 {
write_index(w, "Procedure Groups", pkg_proc_groups[:]) fmt.wprintf(w, `<li><a href="#pkg-{0:s}">{0:s}</a>`, eo.name)
write_index(w, "Types", pkg_types[:]) fmt.wprintln(w, `<ul>`)
write_index(w, "Variables", pkg_vars[:]) for e in eo.entities {
write_index(w, "Constants", pkg_consts[:]) fmt.wprintf(w, "<li><a href=\"#{0:s}\">{0:s}</a></li>\n", str(e.name))
}
fmt.wprintln(w, "</ul>")
fmt.wprintln(w, "</li>")
}
write_link(w, "pkg-source-files", "Source Files") write_link(w, "pkg-source-files", "Source Files")
fmt.wprintln(w, `</ul>`) fmt.wprintln(w, `</ul>`)
fmt.wprintln(w, `</nav>`) fmt.wprintln(w, `</nav>`)
+12 -1
View File
@@ -91,6 +91,17 @@ a:hover > .a-hidden {
opacity: 100; opacity: 100;
} }
.documentation h4 { article.documentation h2 {
border-bottom: 1px dashed #c6c8ca;
padding-bottom: 0.5rem;
}
section.documentation h3 {
font-size: calc(1.1rem + .2vw); font-size: calc(1.1rem + .2vw);
}
.doc-index h3 {
border-bottom: 1px solid #c6c8ca;
padding-bottom: 0.25rem;
} }