-
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(docs-utils,dgeni): generate breadcrumbs from doc path (#3047)
--------- Co-authored-by: xelaint <xelaint@gmail.com>
- Loading branch information
Showing
24 changed files
with
393 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './type'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/** | ||
* A breadcrumb represents a level in the navigation hierarchy of a webpage. | ||
* A common example is the category that contains a product, e.g. T-Shirts > Men > BallerTee. | ||
*/ | ||
export interface DaffBreadcrumb { | ||
/** | ||
* The human-readable label. | ||
*/ | ||
label: string; | ||
/** | ||
* The path of the breadcrumb. | ||
*/ | ||
path: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { crossOsFilename } from './cross-os-filename'; | ||
export * from './kind/public_api'; | ||
export * from './breadcrumb/public_api'; | ||
export * from './path'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Document } from 'dgeni'; | ||
|
||
import { FilterableProcessor } from '../utils/filterable-processor.type'; | ||
|
||
export interface PathedDocument extends Document { | ||
path: string; | ||
} | ||
|
||
export const ABSOLUTIFY_PATHS_PROCESSOR_NAME = 'absolutifyPaths'; | ||
|
||
/** | ||
* Converts paths to absolute if they are not already. | ||
*/ | ||
export class AbsolutifyPathsProcessor implements FilterableProcessor { | ||
readonly name = ABSOLUTIFY_PATHS_PROCESSOR_NAME; | ||
readonly $runAfter = ['absolutify-paths']; | ||
readonly $runBefore = ['paths-absolutified']; | ||
|
||
docTypes = ['package']; | ||
|
||
$process(docs: Array<PathedDocument>): Array<PathedDocument> { | ||
return docs.map((doc) => { | ||
if (doc.path[0] !== '/') { | ||
doc.path = `/${doc.path}`; | ||
} | ||
return doc; | ||
}); | ||
} | ||
} | ||
|
||
export const ABSOLUTIFY_PATHS_PROCESSOR_PROVIDER = <const>[ | ||
ABSOLUTIFY_PATHS_PROCESSOR_NAME, | ||
() => new AbsolutifyPathsProcessor(), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { Document } from 'dgeni'; | ||
|
||
import { | ||
DAFF_DOC_KIND_PATH_SEGMENT_MAP, | ||
DAFF_DOCS_DESIGN_PATH, | ||
DAFF_DOCS_PATH, | ||
DaffBreadcrumb, | ||
DaffDocKind, | ||
} from '@daffodil/docs-utils'; | ||
|
||
import { KindedDocument } from './add-kind'; | ||
import { ParentedDocument } from '../transforms/daffodil-api-package/processors/add-subpackage-exports'; | ||
import { FilterableProcessor } from '../utils/filterable-processor.type'; | ||
|
||
const getStaticBreadcrumb = (segment: string, parent: string): DaffBreadcrumb => { | ||
switch (segment) { | ||
case DAFF_DOCS_PATH: | ||
return { | ||
label: 'Docs', | ||
path: `${parent}/${DAFF_DOCS_PATH}`, | ||
}; | ||
|
||
case DAFF_DOCS_DESIGN_PATH: | ||
return { | ||
label: 'Design', | ||
path: `${parent}/${DAFF_DOCS_DESIGN_PATH}`, | ||
}; | ||
|
||
case DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.GUIDE]: | ||
return { | ||
label: 'Guides', | ||
path: `${parent}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.GUIDE]}`, | ||
}; | ||
|
||
case DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.EXPLANATION]: | ||
return { | ||
label: 'Explanations', | ||
path: `${parent}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.EXPLANATION]}`, | ||
}; | ||
|
||
case DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.PACKAGE]: | ||
return { | ||
label: 'Packages', | ||
path: `${parent}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.PACKAGE]}`, | ||
}; | ||
|
||
case DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.EXAMPLE]: | ||
return { | ||
label: 'Examples', | ||
path: `${parent}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.EXAMPLE]}`, | ||
}; | ||
|
||
case DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.API]: | ||
return { | ||
label: 'API', | ||
path: `${parent}/${DAFF_DOC_KIND_PATH_SEGMENT_MAP[DaffDocKind.API]}`, | ||
}; | ||
|
||
default: | ||
return null; | ||
} | ||
}; | ||
|
||
/** | ||
* A dgeni document which has breadcrumbs added. | ||
*/ | ||
export interface BreadcrumbedDocument extends Document { | ||
breadcrumbs: Array<DaffBreadcrumb>; | ||
} | ||
|
||
const getParents = (doc: ParentedDocument): Array<ParentedDocument> => | ||
doc.parent | ||
? [...getParents(doc.parent), doc.parent] | ||
: []; | ||
|
||
/** | ||
* Truncates the label of a breadcrumb such that it will only be the info not contained in the parent. | ||
*/ | ||
const truncateLabel = (label: string, parent: string): string => | ||
label.replace(`${parent}/`, ''); | ||
|
||
export const BREADCRUMB_PROCESSOR_NAME = 'breadcrumb'; | ||
|
||
export class BreadcrumbProcessor implements FilterableProcessor { | ||
readonly name = BREADCRUMB_PROCESSOR_NAME; | ||
readonly $runAfter = ['paths-absolutified']; | ||
readonly $runBefore = ['rendering-docs']; | ||
|
||
docTypes = []; | ||
|
||
constructor( | ||
private aliasMap, | ||
) {} | ||
|
||
private getBreadcrumbs(doc: ParentedDocument & KindedDocument): Array<DaffBreadcrumb> { | ||
const segments = doc.path.split('/'); | ||
const breadcrumbs = segments | ||
.map((segment, i) => getStaticBreadcrumb(segment, segments.slice(0, i).join('/'))) | ||
.filter((b) => !!b); | ||
|
||
// once all static breadcrumbs are generated, | ||
// create dynamic breadcrumbs for doc kinds that need them | ||
// TODO: determine actual requirements for this feature | ||
switch (doc.kind) { | ||
case DaffDocKind.PACKAGE: | ||
const parents_ = segments | ||
// get all the dynamic segments not including the last (which is the current doc) | ||
// we only want to process dynamic parents here | ||
.slice(breadcrumbs.length + 1, segments.length - 1) | ||
// look up parents based on an alias built from segments | ||
.flatMap((_, i, ids) => this.aliasMap.getDocs(ids.slice(0, i + 1).join('/'))); | ||
breadcrumbs.push( | ||
// turn the parent docs into breadcrumbs | ||
...parents_.map((parent, i) => ({ | ||
label: truncateLabel(parent.title, parents_[i - 1]?.title), | ||
path: parent.path, | ||
})), | ||
{ | ||
label: parents_.length > 0 ? truncateLabel(doc.title, parents_[parents_.length - 1].title) : doc.title, | ||
path: doc.path, | ||
}, | ||
); | ||
break; | ||
|
||
case DaffDocKind.API: | ||
if (doc.parent) { | ||
// build a list of parents to this doc and turn them into breadcrumbs | ||
const parents = [ | ||
...getParents(doc.parent), | ||
doc.parent, | ||
]; | ||
breadcrumbs.push( | ||
...parents.map((parent, i) => ({ | ||
label: truncateLabel(parent.name, parents[i - 1]?.name), | ||
path: parent.path, | ||
})), | ||
{ | ||
label: parents.length > 0 ? truncateLabel(doc.name, parents[parents.length - 1].name) : doc.name, | ||
path: doc.path, | ||
}, | ||
); | ||
} | ||
break; | ||
|
||
case DaffDocKind.GUIDE: | ||
case DaffDocKind.EXPLANATION: | ||
case DaffDocKind.EXAMPLE: | ||
default: | ||
breadcrumbs.push({ | ||
label: doc.name || doc.title, | ||
path: doc.path, | ||
}); | ||
break; | ||
} | ||
|
||
return breadcrumbs; | ||
} | ||
|
||
$process(docs: Array<ParentedDocument & KindedDocument>): Array<BreadcrumbedDocument> { | ||
return docs.map(doc => ({ | ||
...doc, | ||
breadcrumbs: this.docTypes.includes(doc.docType) | ||
? this.getBreadcrumbs(doc) | ||
: [], | ||
})); | ||
} | ||
}; | ||
|
||
export const BREADCRUMB_PROCESSOR_PROVIDER = <const>[ | ||
BREADCRUMB_PROCESSOR_NAME, | ||
(aliasMap) => new BreadcrumbProcessor(aliasMap), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.