docfx icon indicating copy to clipboard operation
docfx copied to clipboard

Support for nested namespaces

Open InariTheFox opened this issue 8 years ago • 22 comments

I believe a very useful feature for DocFX is to support nested namespaces, I realize that this in itself can be quite a challenge, but having the option to turn this feature on would help to generate less confusing and a more compact TOC, especially in much larger projects.

InariTheFox avatar Apr 21 '16 14:04 InariTheFox

:+1: Yes, please! And proper tree view control for nested namespaces (it could be an option or special template). screenshot

On the screenshot the font size for entries was custom selected (I've modified the template), so AtomicTorch.CBND.GameAPI. matches exactly the width of the column, otherwise it wraps really weird:

screenshot (wrapped)

I hope it will be addressed soon...

Regards!

aienabled avatar May 10 '16 04:05 aienabled

Is there any news on this?

joshuaavalon avatar Nov 14 '16 02:11 joshuaavalon

Looks like this only relates to TOC structure. A quick work around for this is to re-format TOC.yml before docfx build, using a custom script.

vicancy avatar May 09 '17 08:05 vicancy

I work on a big project and would appreciate to have it out of the box. Still not progress yet?

jaroslaw-weber avatar Nov 29 '18 03:11 jaroslaw-weber

Looks like this only relates to TOC structure. A quick work around for this is to re-format TOC.yml before docfx build, using a custom script.

try this:

var fs = require('fs');
var yaml = require('js-yaml');
var toc = yaml.safeLoad(fs.readFileSync('./api/toc.yml'));

var namespaces = {};

for(var i=0; i<toc.length; i++) {
    var fullnamespace = toc[i].uid;
    var splitnamespace = fullnamespace.split('.');

    var parent = namespaces;

    for(var j = 0; j < splitnamespace.length; j++) {
        var partialnamespace = splitnamespace[j];

        if(parent[partialnamespace] == undefined) {
            parent[partialnamespace] = {};
        }
        parent = parent[partialnamespace];
    }

    if(parent.items == undefined) {
        parent.items = toc[i].items;
    }
    else {
        parent.items.push(toc[i]);
    }
}

var newToc = [];

function recurse(obj, path="") {
    var items = [];
    Object.keys(obj).forEach((e, i)=>{
        if(e!="items") {
            var newPath;
            if(path=="") {
                newPath = e;
            }
            else {
                newPath = path + '.' + e;
            }
            var newObj = {uid: newPath, name: newPath, items: obj[e].items || []}
            newObj.items.push(...recurse(obj[e], newPath));
            items.push(newObj);
        }
    });
    return items;
}

var items = recurse(namespaces);

fs.writeFileSync('./api/toc.yml', yaml.safeDump(items));

BernsteinA avatar Jan 21 '19 18:01 BernsteinA

Hello BernsteinA, thanks a lot for this script... really a pity not to have nested namespaces... Maybe you can help me to quickly find where this script is hooked into DocFx. I'm a little confused by the different hook/plugin options DocFx offers. Can you tell me which DocFx howto is the right one for this??

Greetings and thanks for your script again!

Onnno avatar Mar 26 '19 11:03 Onnno

@Onnno I'm not using any of the docfx hooks. There probably is a way to do it automatically, but I just run that script manually after docfx metadata (and before docfx build)

BernsteinA avatar Mar 26 '19 13:03 BernsteinA

Ok, thanks :-).

Onnno avatar Mar 27 '19 09:03 Onnno

This would be an enabler feature for me. Currently the TOC is useless as our namespaces are just too long. This in turn makes the output difficult for user to use.

Raise cost of use mean acceptance never gained.

RobSmyth avatar Nov 13 '19 08:11 RobSmyth

I scripted the whole thing and it finally works :-). If you push me again I'll try to find some time to publish it. It is a little hacky approach - however, it was the only way I could do it and it works fine. I had to modify docFx code slightly due to a bug and a small missing feature. I also had to add scripts in some places. I could push the project online if I clean it from stuff proprietary to the company I work for. Vote for it if you like so it will push me to do so soon.

A quick publish should be possible.

Onnno avatar Nov 14 '19 17:11 Onnno

LOL

If you push me again I'll try to find some time to publish it.

Push!

RobSmyth avatar Nov 21 '19 08:11 RobSmyth

Go @Onnno, go @Onnno! PUSH!

Sternerson avatar Dec 12 '19 07:12 Sternerson

Ok, I talked to my boss and got the go :-) I'll have to cleanup/prepare it for you before publish. I think I'll get it done within this or next week. I'll link to it from here... You may consider it as a christmas present though I cannot prevent you from unpacking it before christmas :-P

Onnno avatar Dec 12 '19 11:12 Onnno

was this ever finished? @Onnno did you ever get to push this?

aggarwalpulkit avatar Jul 09 '20 18:07 aggarwalpulkit

I use @BernsteinA script with a very small modification, in the name I pass e instead of newPath and now it really short. My first 3 levels in the namespace have no code (my root namespace is along the lines of MyCompany.Modules.MyModule ) so it really made it look nice now:

image

valadas avatar Feb 11 '21 02:02 valadas

I scripted the whole thing and it finally works :-). If you push me again I'll try to find some time to publish it. It is a little hacky approach - however, it was the only way I could do it and it works fine. I had to modify docFx code slightly due to a bug and a small missing feature. I also had to add scripts in some places. I could push the project online if I clean it from stuff proprietary to the company I work for. Vote for it if you like so it will push me to do so soon.

A quick publish should be possible.

Has this been published anywhere?

JamesHurburgh avatar Jun 01 '21 01:06 JamesHurburgh

Past, I worked on the solution via a custom template script: WIP: https://gist.github.com/wcoder/1ffaae564978d048357c32652e3f84c7

wcoder avatar Nov 23 '21 11:11 wcoder

Looks like this only relates to TOC structure. A quick work around for this is to re-format TOC.yml before docfx build, using a custom script.

try this:

var fs = require('fs');
var yaml = require('js-yaml');
var toc = yaml.safeLoad(fs.readFileSync('./api/toc.yml'));

var namespaces = {};

for(var i=0; i<toc.length; i++) {
    var fullnamespace = toc[i].uid;
    var splitnamespace = fullnamespace.split('.');

    var parent = namespaces;

    for(var j = 0; j < splitnamespace.length; j++) {
        var partialnamespace = splitnamespace[j];

        if(parent[partialnamespace] == undefined) {
            parent[partialnamespace] = {};
        }
        parent = parent[partialnamespace];
    }

    if(parent.items == undefined) {
        parent.items = toc[i].items;
    }
    else {
        parent.items.push(toc[i]);
    }
}

var newToc = [];

function recurse(obj, path="") {
    var items = [];
    Object.keys(obj).forEach((e, i)=>{
        if(e!="items") {
            var newPath;
            if(path=="") {
                newPath = e;
            }
            else {
                newPath = path + '.' + e;
            }
            var newObj = {uid: newPath, name: newPath, items: obj[e].items || []}
            newObj.items.push(...recurse(obj[e], newPath));
            items.push(newObj);
        }
    });
    return items;
}

var items = recurse(namespaces);

fs.writeFileSync('./api/toc.yml', yaml.safeDump(items));

How to use this script before build?

gumbarros avatar Dec 07 '21 13:12 gumbarros

Workaround:

  1. Install NodeJS
  2. Create a .js file with this content in the same folder of docfx.json
  3. Run docfx metadata
  4. Run node your_file.js
  5. Run docfx build --serve
  6. Profit

image

gumbarros avatar Dec 08 '21 14:12 gumbarros

@gumbarros

How to use this script before build?

I run that script manually after docfx metadata (and before docfx build)

BernsteinA avatar Dec 08 '21 15:12 BernsteinA

PowerShell Script

unflatten-namespaces.ps1 I've taken the liberty to port @BernsteinA's NodeJS script to PowerShell. No NodeJS dependencies, cross platform, and copy-paste for Azure DevOps pipelines.

Works like a charm. I'll probably update it with some nice-to-haves, like putting folders at the top instead of the bottom and hiding the root namespace when there's only one item. image image

Arlodotexe avatar Jan 19 '22 02:01 Arlodotexe

I made an extension for toc.js, it can be used in a template, but it is raw and bugs are possible.

https://github.com/deriglazoff/documentation/blob/main/templates/darkfx/toc.extension.js image=> image

deriglazoff avatar Apr 30 '22 14:04 deriglazoff

I have the same problem ... what can i use ?

EJoffre avatar Dec 05 '22 15:12 EJoffre

I have the same problem ... what can i use ?

You can use like us

nested_namespaces.js implementation https://github.com/JJConsulting/JJMasterData/blob/main/doc/JJMasterData.Documentation/server.bat

Result https://portal.jjconsulting.tech/jjdoc/

gumbarros avatar Dec 05 '22 15:12 gumbarros

I's work ! Thanks :)

EJoffre avatar Dec 08 '22 08:12 EJoffre

I've created a pull request that will add an option for this in the docfx.json.

NanoBob avatar Jan 29 '23 12:01 NanoBob

How do we use it now? I went through the PR code and it adds the option "tocNamespaceStyle" to the docfx.json. However, when trying to use it, nothing happens. As for the values that can be used, I assume it is "Flattened" and "Nested", as per definition in the enum. There is no error / warning message that anything is wrong, so I don't know what I am doing wrong.

MiTschMR avatar Mar 06 '23 09:03 MiTschMR

@MiTschMR use namespaceLayout in metadata section of your docfx.json:

{
  "metadata": [
    {
      ...
      "namespaceLayout": "nested"
    }
  ]
}

wcoder avatar Mar 06 '23 09:03 wcoder

Thanks a lot, the nesting doesn't yet work, but at least it shows it in the log that it is in experimental state. Most likely I am doing something wrong, or it may be my filter config, will have to check.

A working example with a screenshot would be very much appreciated nonetheless 😄

MiTschMR avatar Mar 06 '23 09:03 MiTschMR

v2.62.2 fixes the bug with the nesting not shown, no config change (except adding the "namespaceLayout" key) required.

Thanks again @wcoder for the help with getting it to run!

MiTschMR avatar Mar 09 '23 09:03 MiTschMR