docs v2
This commit is contained in:
180
autogen/mdgen.js
Normal file
180
autogen/mdgen.js
Normal file
@@ -0,0 +1,180 @@
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
const { XMLParser } = require("fast-xml-parser");
|
||||
|
||||
const xmlAPIPath = path.join(__dirname, "../", "xml", "types")
|
||||
const mdAPIPath = path.join(__dirname, "../", "docs/api", "types")
|
||||
const xmlEnumPath = path.join(__dirname, "../", "xml", "enums")
|
||||
const mdEnumPath = path.join(__dirname, "../", "docs/api", "enums")
|
||||
|
||||
if (!fs.existsSync(mdAPIPath)) {
|
||||
fs.mkdirSync(mdAPIPath, { recursive: true })
|
||||
}
|
||||
|
||||
if (!fs.existsSync(xmlAPIPath)) {
|
||||
fs.mkdirSync(xmlAPIPath, { recursive: true })
|
||||
}
|
||||
|
||||
if (!fs.existsSync(mdEnumPath)) {
|
||||
fs.mkdirSync(mdEnumPath, { recursive: true })
|
||||
}
|
||||
|
||||
if (!fs.existsSync(xmlEnumPath)) {
|
||||
fs.mkdirSync(xmlEnumPath, { recursive: true })
|
||||
}
|
||||
|
||||
const parser = new XMLParser();
|
||||
|
||||
// Process API Classes
|
||||
const xmlFiles = fs.readdirSync(xmlAPIPath).filter(file => file.endsWith('.xml'));
|
||||
|
||||
for (const xmlFile of xmlFiles) {
|
||||
const xmlPath = path.join(xmlAPIPath, xmlFile);
|
||||
const xmlContent = fs.readFileSync(xmlPath, "utf-8");
|
||||
const data = parser.parse(xmlContent);
|
||||
|
||||
if (!data.ClassDef) continue;
|
||||
|
||||
const c = data.ClassDef;
|
||||
const className = path.basename(xmlFile, '.xml');
|
||||
let mdPath = path.join(mdAPIPath, className + ".md")
|
||||
let mk = ""
|
||||
|
||||
function appendLine(str) {
|
||||
mk += str + "\n"
|
||||
}
|
||||
|
||||
appendLine("---")
|
||||
appendLine("title: " + c.Name)
|
||||
appendLine("description:")
|
||||
appendLine("---")
|
||||
appendLine("")
|
||||
appendLine("# " + c.Name)
|
||||
|
||||
if (c.BaseType) {
|
||||
appendLine("")
|
||||
appendLine(`{{ inherits("${c.BaseType}") }}`)
|
||||
}
|
||||
|
||||
appendLine("")
|
||||
appendLine(c.Description)
|
||||
appendLine("")
|
||||
|
||||
if (c.IsStatic) {
|
||||
appendLine(`{{ staticclass(${c.Name.replace("Service", "")}) }}`)
|
||||
appendLine("")
|
||||
}
|
||||
|
||||
if (c.IsAbstract) {
|
||||
appendLine("{{ abstract() }}")
|
||||
appendLine("")
|
||||
}
|
||||
|
||||
if (!c.IsInstantiatable) {
|
||||
appendLine("{{ notnewable() }}")
|
||||
appendLine("")
|
||||
}
|
||||
|
||||
appendLine("")
|
||||
appendLine("## Properties")
|
||||
appendLine("")
|
||||
|
||||
const properties = c.Properties ? (Array.isArray(c.Properties) ? c.Properties : [c.Properties]) : [];
|
||||
for (const prop of properties) {
|
||||
appendLine(`### ${prop.Name}:${prop.Type} { property }`)
|
||||
appendLine(``)
|
||||
appendLine(prop.Description || "Missing documentation!")
|
||||
appendLine(``)
|
||||
}
|
||||
|
||||
appendLine("")
|
||||
appendLine("## Methods")
|
||||
appendLine("")
|
||||
|
||||
const methods = c.Methods ? (Array.isArray(c.Methods) ? c.Methods : [c.Methods]) : [];
|
||||
for (const m of methods) {
|
||||
if (m.IsObsolete) continue
|
||||
let params = []
|
||||
|
||||
const parameters = m.Parameters ? (Array.isArray(m.Parameters) ? m.Parameters : [m.Parameters]) : [];
|
||||
for (const p of parameters) {
|
||||
params.push(`${p.Name};${p.Type}${p.IsOptional ? "?" : ""}`)
|
||||
}
|
||||
|
||||
appendLine(`### ${m.Name}(${params.join(",")}):${m.ReturnType || "void"} { method }`)
|
||||
appendLine(``)
|
||||
appendLine(m.Description || "Missing documentation!")
|
||||
appendLine(``)
|
||||
}
|
||||
|
||||
appendLine("")
|
||||
appendLine("## Events")
|
||||
appendLine("")
|
||||
|
||||
const events = c.Events ? (Array.isArray(c.Events) ? c.Events : [c.Events]) : [];
|
||||
for (const e of events) {
|
||||
let args = []
|
||||
|
||||
const aargs = e.Arguments ? (Array.isArray(e.Arguments) ? e.Arguments : [e.Arguments]) : [];
|
||||
for (const arg of aargs) {
|
||||
args.push(`${arg.Name};${arg.Type}`)
|
||||
}
|
||||
|
||||
appendLine(`### ${e.Name}(${args.join(",")}) { event }`)
|
||||
appendLine(``)
|
||||
appendLine(e.Description || "")
|
||||
appendLine(``)
|
||||
}
|
||||
|
||||
fs.writeFileSync(mdPath, mk)
|
||||
}
|
||||
|
||||
console.log(`Converted ${xmlFiles.length} XML files to Markdown`)
|
||||
|
||||
// Process Enums
|
||||
const xmlEnumFiles = fs.readdirSync(xmlEnumPath).filter(file => file.endsWith('.xml'));
|
||||
|
||||
for (const xmlFile of xmlEnumFiles) {
|
||||
const xmlPath = path.join(xmlEnumPath, xmlFile);
|
||||
const xmlContent = fs.readFileSync(xmlPath, "utf-8");
|
||||
const data = parser.parse(xmlContent);
|
||||
|
||||
if (!data.EnumDef) continue;
|
||||
|
||||
const e = data.EnumDef;
|
||||
const enumName = path.basename(xmlFile, '.xml');
|
||||
let mdPath = path.join(mdEnumPath, enumName + ".md")
|
||||
let mk = ""
|
||||
|
||||
function appendLine(str) {
|
||||
mk += str + "\n"
|
||||
}
|
||||
|
||||
appendLine("---")
|
||||
appendLine("title: " + e.Name)
|
||||
appendLine("description: " + (e.Description && e.Description !== "Missing Documentation" ? e.Description : ""))
|
||||
appendLine("---")
|
||||
appendLine("")
|
||||
appendLine("# " + e.Name)
|
||||
appendLine("")
|
||||
|
||||
if (e.Description && e.Description !== "Missing Documentation") {
|
||||
appendLine(e.Description)
|
||||
appendLine("")
|
||||
}
|
||||
|
||||
appendLine("| Name | Description |")
|
||||
appendLine("| --- | --- |")
|
||||
|
||||
const options = e.Options ? (Array.isArray(e.Options) ? e.Options : [e.Options]) : [];
|
||||
for (const option of options) {
|
||||
const optionName = typeof option === 'string' ? option : option.Name;
|
||||
const optionDesc = typeof option === 'string' ? "" : (option.Description || "");
|
||||
const displayDesc = optionDesc === "Missing Documentation" ? "" : optionDesc;
|
||||
appendLine(`| \`${e.Name}.${optionName}\` | ${displayDesc} |`)
|
||||
}
|
||||
|
||||
fs.writeFileSync(mdPath, mk)
|
||||
}
|
||||
|
||||
console.log(`Converted ${xmlEnumFiles.length} enum XML files to Markdown`)
|
||||
42
autogen/package-lock.json
generated
Normal file
42
autogen/package-lock.json
generated
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "autogen",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"fast-xml-parser": "^5.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-xml-parser": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.3.tgz",
|
||||
"integrity": "sha512-2O3dkPAAC6JavuMm8+4+pgTk+5hoAs+CjZ+sWcQLkX9+/tHRuTkQh/Oaifr8qDmZ8iEHb771Ea6G8CdwkrgvYA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"strnum": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"fxparser": "src/cli/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/strnum": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz",
|
||||
"integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
autogen/package.json
Normal file
5
autogen/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"fast-xml-parser": "^5.3.3"
|
||||
}
|
||||
}
|
||||
163
autogen/xmlgen.js
Normal file
163
autogen/xmlgen.js
Normal file
@@ -0,0 +1,163 @@
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
const { XMLBuilder, XMLParser } = require("fast-xml-parser");
|
||||
|
||||
const xmlAPIPath = path.join(__dirname, "../", "xml", "types")
|
||||
const xmlEnumPath = path.join(__dirname, "../", "xml", "enums")
|
||||
|
||||
if (!fs.existsSync(xmlAPIPath)) {
|
||||
fs.mkdirSync(xmlAPIPath, { recursive: true })
|
||||
}
|
||||
|
||||
if (!fs.existsSync(xmlEnumPath)) {
|
||||
fs.mkdirSync(xmlEnumPath, { recursive: true })
|
||||
}
|
||||
|
||||
const data = JSON.parse(fs.readFileSync("def.json", "utf-8"))
|
||||
|
||||
const parser = new XMLParser();
|
||||
const builder = new XMLBuilder({
|
||||
format: true
|
||||
});
|
||||
|
||||
// Process Classes
|
||||
for (const c of data.Classes) {
|
||||
let xmlPath = path.join(xmlAPIPath, c.Name + ".xml")
|
||||
|
||||
let obj = {
|
||||
...c,
|
||||
Properties: [],
|
||||
Methods: [],
|
||||
Events: [],
|
||||
}
|
||||
|
||||
// Load existing data if file exists
|
||||
let existingDescriptions = { Properties: {}, Methods: {}, Events: {} };
|
||||
let existingArguments = { Events: {} };
|
||||
let existingClassDescription = "Missing Documentation";
|
||||
|
||||
if (fs.existsSync(xmlPath)) {
|
||||
const existingXml = fs.readFileSync(xmlPath, "utf-8");
|
||||
const existingData = parser.parse(existingXml);
|
||||
|
||||
if (existingData.ClassDef) {
|
||||
// Preserve existing class description
|
||||
if (existingData.ClassDef.Description) {
|
||||
existingClassDescription = existingData.ClassDef.Description;
|
||||
}
|
||||
|
||||
// Build lookup maps for existing descriptions
|
||||
if (existingData.ClassDef.Properties) {
|
||||
const props = Array.isArray(existingData.ClassDef.Properties)
|
||||
? existingData.ClassDef.Properties
|
||||
: [existingData.ClassDef.Properties];
|
||||
props.forEach(p => {
|
||||
if (p.Name) existingDescriptions.Properties[p.Name] = p.Description || "";
|
||||
});
|
||||
}
|
||||
|
||||
if (existingData.ClassDef.Methods) {
|
||||
const methods = Array.isArray(existingData.ClassDef.Methods)
|
||||
? existingData.ClassDef.Methods
|
||||
: [existingData.ClassDef.Methods];
|
||||
methods.forEach(m => {
|
||||
if (m.Name) existingDescriptions.Methods[m.Name] = m.Description || "";
|
||||
});
|
||||
}
|
||||
|
||||
if (existingData.ClassDef.Events) {
|
||||
const events = Array.isArray(existingData.ClassDef.Events)
|
||||
? existingData.ClassDef.Events
|
||||
: [existingData.ClassDef.Events];
|
||||
events.forEach(e => {
|
||||
if (e.Name) {
|
||||
existingDescriptions.Events[e.Name] = e.Description || "";
|
||||
existingArguments.Events[e.Name] = e.Arguments || "";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add class description
|
||||
obj.Description = existingClassDescription;
|
||||
|
||||
// Add properties
|
||||
for (const prop of c.Properties) {
|
||||
obj.Properties.push({
|
||||
...prop,
|
||||
Description: existingDescriptions.Properties[prop.Name] || "Missing Documentation"
|
||||
})
|
||||
}
|
||||
|
||||
// Add methods
|
||||
for (const m of c.Methods) {
|
||||
if (m.IsObsolete) continue
|
||||
obj.Methods.push({
|
||||
...m,
|
||||
Description: existingDescriptions.Methods[m.Name] || "Missing Documentation"
|
||||
})
|
||||
}
|
||||
|
||||
// Add events
|
||||
for (const e of c.Events) {
|
||||
obj.Events.push({
|
||||
...e,
|
||||
Description: existingDescriptions.Events[e.Name] || "Missing Documentation",
|
||||
Arguments: existingArguments.Events[e.Name] || ""
|
||||
})
|
||||
}
|
||||
|
||||
const xmlContent = builder.build({
|
||||
"?xml": "",
|
||||
ClassDef: obj
|
||||
});
|
||||
fs.writeFileSync(xmlPath, xmlContent)
|
||||
}
|
||||
|
||||
// Process Enums
|
||||
for (const e of data.Enums) {
|
||||
let xmlPath = path.join(xmlEnumPath, e.Name + ".xml")
|
||||
|
||||
let obj = {
|
||||
...e,
|
||||
Options: []
|
||||
}
|
||||
|
||||
let existingDescriptions = {};
|
||||
let existingEnumDescription = "";
|
||||
if (fs.existsSync(xmlPath)) {
|
||||
const existingXml = fs.readFileSync(xmlPath, "utf-8");
|
||||
const existingData = parser.parse(existingXml);
|
||||
|
||||
if (existingData.EnumDef) {
|
||||
existingEnumDescription = existingData.EnumDef.Description || "";
|
||||
|
||||
if (existingData.EnumDef.Options) {
|
||||
const options = Array.isArray(existingData.EnumDef.Options)
|
||||
? existingData.EnumDef.Options
|
||||
: [existingData.EnumDef.Options];
|
||||
options.forEach(o => {
|
||||
if (o.Name) existingDescriptions[o.Name] = o.Description || "";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add enum description
|
||||
obj.Description = existingEnumDescription || "Missing Documentation";
|
||||
|
||||
// Add options
|
||||
for (const option of e.Options) {
|
||||
obj.Options.push({
|
||||
Name: option,
|
||||
Description: existingDescriptions[option] || ""
|
||||
})
|
||||
}
|
||||
|
||||
const xmlContent = builder.build({
|
||||
"?xml": "",
|
||||
EnumDef: obj
|
||||
});
|
||||
fs.writeFileSync(xmlPath, xmlContent)
|
||||
}
|
||||
Reference in New Issue
Block a user