Skip to content

Commit

Permalink
improve net code TOC
Browse files Browse the repository at this point in the history
  • Loading branch information
iJungleboy committed Mar 19, 2024
1 parent 722c60b commit 27f12c5
Show file tree
Hide file tree
Showing 3 changed files with 376 additions and 1 deletion.
186 changes: 186 additions & 0 deletions 2sxc Docs Generator/templates/2sxc/toc-tools-new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@

const dbg = require('./toc-debug.js');

// Polyfill for Object.assign
const polyfills = require('./polyfill-object.assign.js');

let count = 0;

function createLeaf(name) {
return {
"name": name,
// "href": "Custom.Dnn.html",
// "topicHref": "Custom.Dnn.html",
// "topicUid": "Custom.Dnn",
"tocHref": null,
"level": 2,
"items": [],
"leaf": true,
"priority": "", // "custom",
// "fullName": "Custom.Dnn"
}
}

// repeat a string X times
function repeatString(part, count) {
if(count <= 0) return "";
var result = "";
for(i = 0; i < count; i++)
result += part;
return result;
}

function isNamespace(name) {
if (!name) return false;

const prefixes = exports.namespacePrefixes;

for (let i = 0; i < prefixes.length; i++)
if (name.indexOf(prefixes[i]) === 0)
return true;
return false;
}

/**
* shorten the namespace with an ellipsis
*/
function shortenNamespace(item) {
// dbg.error("shortenNamespace - exports:", exports);
const separator = exports.nameSeparator; // '.';
item.fullName = item.name;
var parts = item.name.split(separator);
var count = parts.length;
if (count > exports.nsKeepParts) {
parts.splice(0, count - exports.nsTruncateToParts);
var newName = repeatString(exports.truncEllipsis, count - exports.nsKeepParts) + parts.join(separator);
item.name = newName;
}
}

function addNodeDefaults(item) {
count++;
polyfills.objectAssign(item, exports.nodeDefaults);
}

/**
* add metadata for the template to prioritizes
* @param {*} item
* @param {*} level
*/
function addNodeData(item, level, debug) {
addNodeDefaults(item);

var found = exports.nodeData[item.topicUid];
if (found) {
if (debug) dbg.warn('JS Debug addMeta - uid:' + item.topicUid);
polyfills.objectAssign(item, found);
}
}

const dbgIsApiToc = false;

/**
* find out if it's the API toc
* @param {*} model
* @returns
*/
function isTopLevelApiToc(model) {
if(!model) return false;

// find out if it's the TOC of the API
if(!(model.items && model.items.length)) return false;

var firstName = model.items[0].topicUid || model.items[0].name;
var match = isNamespace(firstName);

// Debug
// if (dbgIsApiToc)
// if (firstName && firstName.indexOf(ns.prefixes[0]) === 0)
// dbg.warn('isApiToc Dnn:', model);

return match;
}

function splitByCondition(items, condition) {
const top = items.filter(condition);
const rest = items.filter(function(i) { return !condition(i) });
return [ top, rest ];
}

function conditionNameSpaceStartsWith(prefix) {
return function(i) { return !!i && i.topicUid && i.topicUid.indexOf(prefix) === 0; };
}


/**
*
* @param {*} node the current node
* @param {*} level the current level, as different levels may change the behavior
* @param {*} modifyNodeCall the callback to modify each node
*/
function processNodeRecursive(node, level, modifyNodeCall) {

// console.error("2dm test processNodeRecursive: 1");

// if (dbgProcessNodeNetApi && dbgProcessNodeJustAFew < dbgProcessNodeJustAFewMax) {
// dbg.log('processNode item: [lvl:' + level + ']:', node);
// dbgProcessNodeJustAFew++;
// if (dbgProcessNodeJustAFew < dbgProcessNodeJustAFewMax)
// dbg.log(`will stop logging activity as we've reached ${dbgProcessNodeJustAFewMax}`)
// }

// debug data on item
// var debugModel = JSON.stringify(item);
// if (dbgProcessNodeNetApi && node.topicUid && node.topicUid.indexOf("Custom") > -1) {
// if (level === 2) {
// node.name = node.name + "x";
// dbg.log('processNode[' + level + "] ", node);
// }
// }

// console.error("2dm test processNodeRecursive: 2");

// Modify the node using the passed in function
modifyNodeCall(node, level);

// console.error("2dm test processNodeRecursive: 3");

// Add level information to the current node
// node.level = level;

// Traverse the tree
if (node.items && node.items.length > 0) {
var length = node.items.length;
for (var i = 0; i < length; i++) {
processNodeRecursive(node.items[i], level + 1, modifyNodeCall);
}
}
}

exports = {
createLeaf: createLeaf,
repeatString: repeatString,
shortenNamespace: shortenNamespace,
isNamespace: isNamespace,
nameSeparator: '.',
truncEllipsis: '...',
nsKeepParts: 3, // Namespace parts to keep, like ToSic.Eav.ImportExport
nsTruncateToParts: 2, // If NS has more parts, keep only the last two (and prefix with ...)
namespacePrefixes: [],

nodeDefaults: {},
addNodeDefaults: addNodeDefaults,

nodeData: {},
addNodeData: addNodeData,

isTopLevelApiToc: isTopLevelApiToc,
split: splitByCondition,
conditionNameSpaceStartsWith: conditionNameSpaceStartsWith,

processNodeRecursive: processNodeRecursive,

test: function() {
console.error("2dm test in toc-tools: ");
}
}
189 changes: 189 additions & 0 deletions 2sxc Docs Generator/templates/2sxc/toc.json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// 2024-03-19 2dm
// Copied from default template
// Believe it generates the JSON for the .net API TOC
// Experimenting with enhancing

const tocTools = require('./toc-tools-new.js');

const highlights = {
"Custom.Data.CustomItem": "💪🏽",
"Custom.Hybrid": "🪴",
"Custom.Hybrid.ApiTyped": "🪴",
"Custom.Hybrid.CodeTyped": "🪴",
"Custom.Hybrid.RazorTyped": "🪴",
"ToSic.Sxc": "⭐",
"ToSic.Sxc.Context": "📟",
"ToSic.Sxc.Data": "🎁",
"ToSic.Sxc.Data.ITypedItem": "🔬",
"ToSic.Sxc.Services": "🌟",
"ToSic.Sxc.Services.ServiceKit16": "🌟",
}


exports.transform = function (model) {

// 2024-03-19 2dm
// Catch the first TOC which is in the .net namespace - first namespace item is the AppCode namespace
model = { ...model };
if (false || model?.items?.[0]?.name == "AppCode") {
// console.error('\n\n2dm in items: \n' + JSON.stringify(model.items[0]));

let items = model.items;

items = flattenNamespace(items, 'Custom');
items = flattenNamespace(items, 'ToSic');

model = { ...model, items: [ ...items ] };

tocTools.processNodeRecursive(model, 1, function (node, level) {
// console.error('2dm node: ' + JSON.stringify(node) + ' level: ' + level);
if (node.topicUid && highlights[node.topicUid]) {
node.name = node.name + ' ' + highlights[node.topicUid];
}
});
}

if (model.memberLayout === 'SeparatePages') {
model = transformMemberPage(model);
}

for (var key in model) {
if (key[0] === '_') {
delete model[key]
}
}

// Original
// return {
// content: JSON.stringify(model)
// };

// new
const stringified = JSON.stringify(model);
// test 2dm
// console.error('\n\n2dm in SeparatePages: \n' + stringified);

return {
content: stringified
};
}

function flattenNamespace(items, ns) {
const index = items.findIndex(item => item.topicUid === ns);
const nsItem = items[index];

// run rename and Highlight on all nsItems
const renamed = nsItem.items.map(item => renameWithNamespaceAndHighlight(item, highlights[item.topicUid]));
nsItem.items = [];

const before = items.splice(0, index + 1);
const after = items.splice(index - 1);
const inserted = [...before, ...renamed, ...after];

return inserted;
}

function renameWithNamespaceAndHighlight(item, highlight = '') {
const name = item.topicUid;// + (highlight ? ' ' + highlight : '');
return { ...item, name };
}




// function findAndHighlight(items, ns, highlight) {
// const index = items.findIndex(item => item.topicUid === ns);
// const nsItem = items[index];
// nsItem.name = nsItem.name + ' ' + highlight;
// return nsItem;
// }

// function findRenameAndRemove(items, ns, newName = null, highlight = '') {
// const index = items.findIndex(item => item.topicUid === ns);
// const nsItem = items[index];
// nsItem.name = newName ?? ns;
// if (highlight) {
// nsItem.name = nsItem.name + ' ' + highlight;
// }
// items.splice(index, 1);
// return nsItem;
// }

function transformMemberPage(model) {
var groupNames = {
"constructor": { key: "constructorsInSubtitle" },
"field": { key: "fieldsInSubtitle" },
"property": { key: "propertiesInSubtitle" },
"method": { key: "methodsInSubtitle" },
"event": { key: "eventsInSubtitle" },
"operator": { key: "operatorsInSubtitle" },
"eii": { key: "eiisInSubtitle" },
};

groupChildren(model);
transformItem(model, 1);
return model;

function groupChildren(item) {
if (!item || !item.items || item.items.length == 0) {
return;
}
var grouped = {};
var items = [];
item.items.forEach(function (element) {
groupChildren(element);
if (element.type) {
var type = element.isEii ? "eii" : element.type.toLowerCase();
if (!grouped.hasOwnProperty(type)) {
if (!groupNames.hasOwnProperty(type)) {
groupNames[type] = {
name: element.type
};
console.log(type + " is not predefined type, use its type name as display name.")
}
grouped[type] = [];
}
grouped[type].push(element);
} else {
items.push(element);
}

}, this);

// With order defined in groupNames
for (var key in groupNames) {
if (groupNames.hasOwnProperty(key) && grouped.hasOwnProperty(key)) {
items.push({
name: model.__global[groupNames[key].key] || groupNames[key].name,
items: grouped[key]
})
}
}

item.items = items;
}

function transformItem(item, level) {
// set to null in case mustache looks up
item.topicHref = item.topicHref || null;
item.tocHref = item.tocHref || null;
item.name = item.name || null;

item.level = level;

if (item.items && item.items.length > 0) {
item.leaf = false;
var length = item.items.length;
for (var i = 0; i < length; i++) {
transformItem(item.items[i], level + 1);
};
} else {
item.items = [];
item.leaf = true;
}
}
}

2 changes: 1 addition & 1 deletion docs/api/dot-net/toc.json

Large diffs are not rendered by default.

0 comments on commit 27f12c5

Please sign in to comment.