Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API TOC categories template #7

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
34 changes: 27 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# docfx-tools

A docfx template for package documentation, patching the modern template to provide stylesheets and scripts for rendering custom workflow containers with copy functionality.
A repository of docfx tools for Bonsai package documentation:
- Docfx Workflow Container template patching the modern template to provide stylesheets and scripts for rendering custom workflow containers with copy functionality.
- Docfx API TOC template that groups nodes by operator type in the table of contents(TOC) on API pages.
- Powershell Scripts that automate several content generation steps for package documentation websites.

## How to use
## How to include

To include this template in a docfx website, first clone this repository as a submodule:
To include this repo in a docfx website, first clone this repository as a submodule:

```
git submodule add https://github.com/bonsai-rx/docfx-tools bonsai
```

Then modify `docfx.json` to include the template immediately after the modern template:
## Using Workflow Container Template

Modify `docfx.json` to include the template immediately after the modern template:

```json
"template": [
Expand Down Expand Up @@ -38,12 +43,27 @@ export default {
}
}
```
## Using API TOC Template

The local installation of docfx needs to be updated to >= v2.77.0.

## Powershell Scripts
```ps1
dotnet tool update docfx
```

This repository also provides helper scripts to automate several content generation steps for package documentation websites.
Modify `docfx.json` to include the api-toc template (note both the workflow container and API TOC template have to be added separately).

```json
"template": [
"default",
"modern",
"bonsai/template",
"bonsai/template/apitoc",
"template"
]
```

### Exporting workflow images
## Powershell Scripts - Exporting workflow images

Exporting SVG images for all example workflows can be automated by placing all `.bonsai` files in a `workflows` folder and calling the below script pointing to the bin directory to include. A bonsai environment is assumed to be available in the `.bonsai` folder in the repository root.

Expand Down
5 changes: 5 additions & 0 deletions template/apitoc/ManagedReference.overwrite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
exports.getOptions = function (model) {
return {
isShared: true
};
}
92 changes: 92 additions & 0 deletions template/apitoc/toc.extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

function defineOperatorType(model){
// Define Bonsai operator types in documentation by checking for an explicit Category tag. If the class does not provide one,
// check the inheritance tree of the class.

const checkForCategory = (category) => model.syntax?.content[0].value.includes(`[WorkflowElementCategory(ElementCategory.${category})]`);
const checkInheritance = (inheritance) => model.inheritance?.some(inherited => inherited.uid.includes(inheritance));

source = checkForCategory('Source') || checkInheritance('Bonsai.Source');
sink = checkForCategory('Sink') || checkInheritance('Bonsai.Sink') || checkInheritance('Bonsai.IO.StreamSink') || checkInheritance('Bonsai.IO.FileSink');
combinator = checkForCategory('Combinator') || checkInheritance('Bonsai.Combinator') || checkInheritance('Bonsai.WindowCombinator');
transform = checkForCategory('Transform') || checkInheritance('Bonsai.Transform') || checkInheritance('Bonsai.Transform');

let operatorType = {}
operatorType.type = sink ? 'sink' : source ? 'source' : transform ? 'transform' : combinator ? 'combinator' : false ;

return operatorType;
}

/**
* This method will be called at the start of exports.transform in toc.html.js and toc.json.js
*/
exports.preTransform = function (model) {

// Checks and applies TOC customisation only to API page
if (model._key === 'api/toc.yml') {

//Setups operator mapping
const typeIndexMap = {
'source': 0,
'transform': 1,
'sink': 2,
'combinator': 3
};

// Iterates through each namespace for packages with multiple namespaces
for (namespace of model.items) {
if (namespace.items) {
itemsItemsLength = namespace.items.length;

// Setups operator categories
let items = [{
'name': 'Sources',
'items': []}, {
'name': 'Transforms',
'items': []}, {
'name': 'Sinks',
'items': []}, {
'name': 'Combinators',
'items': []}, {
'name': 'Helper Classes',
'items': []}, {
'name': 'Enums',
'items': []
}];

// Iterates through each item in the namespace and sorts them into categories
for (let i = 0; i < itemsItemsLength; i++) {
globalYml = '~/api/' + namespace.items[i].topicUid + '.yml';
if (model.__global._shared[globalYml] && model.__global._shared[globalYml].type === 'class'){
operatorType = defineOperatorType(model.__global._shared[globalYml]);

const index = typeIndexMap[operatorType.type]
if (index !== undefined) {
items[index].items.push(namespace.items[i]);
}
else {
items[4].items.push(namespace.items[i]);
}
}
if (model.__global._shared[globalYml] && model.__global._shared[globalYml].type === 'enum'){
items[5].items.push(namespace.items[i]);
}
}

// Filters out empty TOC categories and sets namespace TOC items
items = items.filter(item => item.items.length > 0);
namespace.items = items;
}
}
}
return model;
}

/**
* This method will be called at the end of exports.transform in toc.html.js and toc.json.js
*/
exports.postTransform = function (model) {
return model;
}