Skip to content

Commit 676e498

Browse files
authored
feat(dgeni,docs,daffio): implement ToC for all doc kinds (#3423)
1 parent d3cee1e commit 676e498

File tree

17 files changed

+76
-39
lines changed

17 files changed

+76
-39
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
<daffio-doc-article [breadcrumbs]="doc().breadcrumbs">
1+
<daffio-doc-article [breadcrumbs]="doc().breadcrumbs" [toc]="doc().tableOfContents">
22
@if (isApiPackage()) {
33
<daffio-api-package [doc]="doc()"></daffio-api-package>
44
} @else {
55
<div [innerHTML]="doc().contents | safe"></div>
6+
@if (doc().examples.length > 0) {
7+
<h2 id="examples">Examples</h2>
8+
}
9+
@for (example of doc().examples; track example.id) {
10+
<h3 [attr.id]="example.id">{{example.caption}}</h3>
11+
<div [innerHTML]="example.body | safe"></div>
12+
}
613
}
714
</daffio-doc-article>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<daffio-doc-article [breadcrumbs]="doc().breadcrumbs">
1+
<daffio-doc-article [breadcrumbs]="doc().breadcrumbs" [toc]="doc().tableOfContents">
22
<div [innerHTML]="doc().contents | safe"></div>
33
</daffio-doc-article>

apps/daffio/src/app/docs/components/table-of-contents/table-of-contents.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import { By } from '@angular/platform-browser';
77
import { RouterTestingModule } from '@angular/router/testing';
88

99
import { DaffLinkSetModule } from '@daffodil/design/link-set';
10-
import { DaffGuideDoc } from '@daffodil/docs-utils';
10+
import { DaffDoc } from '@daffodil/docs-utils';
1111

1212
import { DaffioDocsTableOfContentsComponent } from './table-of-contents.component';
1313
import { DaffioDocsFactory } from '../../testing/factories/docs.factory';
1414

1515
describe('DaffioDocsTableOfContentsComponent', () => {
1616
let component: DaffioDocsTableOfContentsComponent;
1717
let fixture: ComponentFixture<DaffioDocsTableOfContentsComponent>;
18-
let stubDaffioDoc: DaffGuideDoc;
18+
let stubDaffioDoc: DaffDoc;
1919

2020
beforeEach(waitForAsync(() => {
2121
TestBed.configureTestingModule({

apps/daffio/src/app/docs/guides/components/guides-content/guides-content.component.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
} from '@angular/core';
66

77
import {
8-
DaffGuideDoc,
8+
DaffDoc,
99
DaffDocKind,
1010
} from '@daffodil/docs-utils';
1111

@@ -23,8 +23,8 @@ import { DaffioDocsDynamicContent } from '../../../dynamic-content/dynamic-conte
2323
DaffioSafeHtmlPipe,
2424
],
2525
})
26-
export class DaffioDocsGuidesContentComponent implements DaffioDocsDynamicContent<DaffGuideDoc> {
26+
export class DaffioDocsGuidesContentComponent implements DaffioDocsDynamicContent<DaffDoc> {
2727
static readonly kind = DaffDocKind.GUIDE;
2828

29-
doc = input<DaffGuideDoc>();
29+
doc = input<DaffDoc>();
3030
}

apps/daffio/src/app/docs/testing/factories/docs.factory.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { sample } from '@daffodil/core';
55
import { DaffModelFactory } from '@daffodil/core/testing';
66
import {
77
DaffDocKind,
8-
DaffGuideDoc,
8+
DaffDoc,
99
} from '@daffodil/docs-utils';
1010

11-
export class MockDoc implements DaffGuideDoc {
11+
export class MockDoc implements DaffDoc {
1212
id = String(faker.datatype.number(1000));
1313
kind = sample(Object.values(DaffDocKind));
1414
title = faker.lorem.words();
@@ -27,7 +27,7 @@ export class MockDoc implements DaffGuideDoc {
2727
@Injectable({
2828
providedIn: 'root',
2929
})
30-
export class DaffioDocsFactory extends DaffModelFactory<DaffGuideDoc>{
30+
export class DaffioDocsFactory extends DaffModelFactory<DaffDoc>{
3131
constructor() {
3232
super(MockDoc);
3333
}

libs/docs-utils/src/doc/api.type.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { DaffDocExample } from './example.type';
21
import { DaffDoc } from './type';
2+
import { DaffDocExample } from '../example/public_api';
33

44
/**
55
* An API doc that includes the type of the symbol.

libs/docs-utils/src/doc/guide.type.ts

-9
This file was deleted.
+10-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
import { DaffApiDoc } from '@daffodil/docs-utils';
2-
3-
import { DaffGuideDoc } from './guide.type';
1+
import { DaffDoc } from './type';
2+
import { DaffDocTableOfContents } from '../toc/public_api';
43

54
/**
65
* A guide doc for a package.
76
*/
8-
export interface DaffPackageGuideDoc extends DaffGuideDoc {
7+
export interface DaffPackageGuideDoc extends DaffDoc {
98
/**
109
* A list of symbol paths exported from the package.
1110
*/
12-
symbols?: Array<string>;
11+
symbols: Array<string>;
12+
/**
13+
* A list of rendered API docs.
14+
*/
15+
api: Array<string>;
1316
/**
14-
* A list of API docs for symbols exported from this package.
17+
* A table of contents for the API section.
1518
*/
16-
api?: Array<DaffApiDoc>;
19+
apiToc: DaffDocTableOfContents;
1720
}

libs/docs-utils/src/doc/public_api.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
export * from './api.type';
2-
export * from './example.type';
3-
export * from './guide.type';
42
export * from './package-guide.type';
5-
export * from './toc.type';
63
export * from './type';

libs/docs-utils/src/doc/type.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { DaffBreadcrumb } from '@daffodil/docs-utils';
2-
1+
import { DaffBreadcrumb } from '../breadcrumb/public_api';
32
import { DaffDocKind } from '../kind/public_api';
3+
import { DaffDocTableOfContents } from '../toc/public_api';
44

55
/**
66
* A basic generated document that represents some piece of documentation.
@@ -11,4 +11,5 @@ export interface DaffDoc {
1111
contents: string;
1212
breadcrumbs: Array<DaffBreadcrumb>;
1313
kind: DaffDocKind;
14+
tableOfContents: DaffDocTableOfContents;
1415
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './type';

libs/docs-utils/src/doc/example.type.ts libs/docs-utils/src/example/type.ts

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
* A usage example.
33
*/
44
export interface DaffDocExample {
5+
/**
6+
* The ID of the example.
7+
* Since not all examples will have captions, a unique is useful for fragment anchor scrolling.
8+
*/
9+
id: string;
510
/**
611
* The short caption describing the example.
712
* This should be just plain text.

libs/docs-utils/src/public_api.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
export { crossOsFilename } from './cross-os-filename';
2-
export * from './kind/public_api';
2+
export * from './path';
3+
34
export * from './breadcrumb/public_api';
4-
export * from './nav/public_api';
55
export * from './doc/public_api';
6-
export * from './path';
6+
export * from './example/public_api';
7+
export * from './kind/public_api';
8+
export * from './nav/public_api';
9+
export * from './toc/public_api';

libs/docs-utils/src/toc/public_api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './type';
File renamed without changes.

tools/dgeni/src/processors/add-api-symbols-to-package.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Document } from 'dgeni';
22
import type { Environment } from 'nunjucks';
33

4+
import { DaffApiDoc } from '@daffodil/docs-utils';
5+
46
import { CollectLinkableSymbolsProcessor } from './collect-linkable-symbols';
57
import { API_TEMPLATES_PATH } from '../transforms/config';
68
import { FilterableProcessor } from '../utils/filterable-processor.type';
@@ -30,8 +32,13 @@ export class AddApiSymbolsToPackagesProcessor implements FilterableProcessor {
3032

3133
const ret = docs.map(doc => {
3234
if (this.docTypes.includes(doc.docType)) {
33-
doc.symbols = CollectLinkableSymbolsProcessor.packages.get(this.lookup(doc))?.map((d) => d.path);
34-
doc.api = CollectLinkableSymbolsProcessor.packages.get(this.lookup(doc))?.map((symbol) => render(this.templateFinder.getFinder()(symbol), { doc: symbol, child: true }));
35+
const exportDocs = CollectLinkableSymbolsProcessor.packages.get(this.lookup(doc));
36+
doc.symbols = exportDocs?.map((d) => d.path);
37+
doc.api = exportDocs?.map((symbol) => render(this.templateFinder.getFinder()(symbol), { doc: symbol, child: true }));
38+
doc.apiToc = exportDocs?.flatMap((symbol: DaffApiDoc) => symbol.tableOfContents.map((entry) => ({
39+
...entry,
40+
lvl: entry.lvl + 1,
41+
})));
3542
}
3643
return doc;
3744
});

tools/dgeni/src/transforms/daffodil-api-package/processors/examples.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import { Document } from 'dgeni';
2+
import { slugify } from 'markdown-toc';
23

3-
import { DaffDocExample } from '@daffodil/docs-utils';
4+
import {
5+
DaffDocExample,
6+
DaffDocTableOfContents,
7+
} from '@daffodil/docs-utils';
48

59
import { MARKDOWN_CODE_PROCESSOR_NAME } from '../../../processors/markdown';
610
import { FilterableProcessor } from '../../../utils/filterable-processor.type';
711

812
export const EXAMPLES_PROCESSOR_NAME = 'examples';
913

14+
const genExamplesToc = (examples: Array<DaffDocExample>): DaffDocTableOfContents =>
15+
examples.map((example) => ({
16+
content: example.caption,
17+
lvl: 3,
18+
slug: example.id,
19+
}));
20+
1021
/**
1122
* Adds subpackage entry point docs to the containing package doc.
1223
*/
@@ -20,10 +31,20 @@ export class ExamplesProcessor implements FilterableProcessor {
2031
$process(docs: Array<Document>): Array<Document> {
2132
return docs.map((doc) => {
2233
if (this.docTypes.includes(doc.docType)) {
23-
doc.examples = doc.tags.tagsByName.get('example')?.map((example): DaffDocExample => ({
34+
doc.examples = doc.tags.tagsByName.get('example')?.map((example, i): DaffDocExample => ({
35+
id: slugify(`${doc.name}-example-${i}`),
2436
caption: example.caption,
2537
body: example.body,
2638
})) || [];
39+
doc.tableOfContents = doc.examples.length > 0 ? [
40+
{
41+
content: 'Examples',
42+
lvl: 2,
43+
// TODO: add doc-specific prefix
44+
slug: 'examples',
45+
},
46+
...genExamplesToc(doc.examples),
47+
] : [];
2748
}
2849
return doc;
2950
});

0 commit comments

Comments
 (0)