Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/webdoc-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ The `template` object is used by the site template.
{
"template": {
"applicationName": "{ <i>webdoc</i> }",
"appBar": {
"items": {
"about": {
"name": "About Us",
"uri": "https://example.com/about-us"
}
}
},
"routes": {
"tutorials": "/faq"
},
"meta": {
"og:title": "webdoc",
"og:description": "webdoc API documentation",
Expand All @@ -114,6 +125,12 @@ The `template` object is used by the site template.
```

* `template.applicationName`: The name of the documented software. This is usually used to fill the app bar and tab title.
* `template.appBar.items`: This key-value object can be used to configure the items in the app bar. The key is an identifier
and to override a built-in item, you'll need to use its specific key (if you're adding more items, the key's specific value
won't matter). For example, if you want to show the tutorials as "Guides", you can set `{ "tutorials": { "name": "Guides" } }`. Each
item defines a name and URI.
* `template.routes`: This can be used to override specific routes generated by the template. For example, you can move the
`tutorials` to be outputted at "/faq" instead of "/tutorials", if desired.
* `template.meta`: (optional) This can be used to define the `<meta>` key-value tags. The `{{url}}` variable can be used
to put in the site URL for each page (you have to provide the `siteDomain` and `siteRoot`).
* `template.repository`: (optional) This can be used to link documents to their location in the source code. The only supported repository is GitHub.
Expand Down
17 changes: 17 additions & 0 deletions packages/webdoc-cli/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,18 @@ type ConfigSchema = {
template?: string,
},
template: {
appBar: {
items: {
[string]: {
name: string,
uri: string,
}
}
},
applicationName: string,
routes: {
tutorials: string,
},
stylesheets: Array<string>,
siteDomain?: string,
siteRoot: string,
Expand Down Expand Up @@ -78,7 +89,13 @@ const defaultConfig: ConfigSchema = {
template: "@webdoc/default-template",
},
template: {
appBar: {
items: {},
},
applicationName: "{ <i>webdoc</i> }",
routes: {
tutorials: "tutorials",
},
siteRoot: "",
stylesheets: [],
mainPage: {
Expand Down
2 changes: 1 addition & 1 deletion packages/webdoc-cli/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ async function main(argv: yargs.Argv) {

const {loadConfig, getTemplate} = require("./config");
const config = loadConfig(argv.config);
const tutorials = loadTutorials(argv.tutorials);
const tutorials = loadTutorials(argv.tutorials, config.template.routes.tutorials);


if (argv.siteRoot) {
Expand Down
12 changes: 7 additions & 5 deletions packages/webdoc-cli/src/load-tutorials/load-tutorials.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const renderer = require("markdown-it")({
.use(require("markdown-it-highlightjs"));

// Loads & parses all the tutorials in the given directory
export function loadTutorials(tutorialsDir?: string): Tutorial[] {
export function loadTutorials(tutorialsDir?: string, tutorialsRoute?: string): Tutorial[] {
if (!tutorialsDir) {
return [];
}
Expand Down Expand Up @@ -80,10 +80,12 @@ export function loadTutorials(tutorialsDir?: string): Tutorial[] {
// Tutorials can be part of the doc-tree!
tutorials.push(createTutorialDoc(
fileName,
path.join("tutorials", relativePath
.replace(".html", "")
.replace(".htm", "")
.replace(".md", "")),
path.join(
typeof tutorialsRoute === "string" ? tutorialsRoute : "tutorials",
relativePath
.replace(".html", "")
.replace(".htm", "")
.replace(".md", "")),
fileContent,
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const HINTS = {

// Crawls the tree searching for the API reference
function crawlReference(doc /*: Doc */, index /*: string */) {
if (!doc.members.length) {
return null;
}

const explorerHierarchy =
buildExplorerHierarchy(doc, doc.packages ? (doc.packages.length > 1) : false);
const tree = buildExplorerTargetsTree(explorerHierarchy, "", index);
Expand Down Expand Up @@ -191,17 +195,10 @@ function buildExplorerTargetsTree(
if (HIERARCHY_SPECIFIERS[doc.type]) {
node.children = {};

node.children["(overview)"] = {
title: "(overview)",
page,
};

if (node.doc.type === "RootDoc") {
node.children["(overview)"].page = index;

node.children.ClassIndex = {
title: "Class Index",
page: linker.createURI("Class-Index"),
if (page) {
node.children["(overview)"] = {
title: "(overview)",
page,
};
}

Expand Down
38 changes: 29 additions & 9 deletions packages/webdoc-default-template/helper/crawl/crawl.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const {linker} = require("../linker");
/*::
import type {
RootDoc,
DocType
} from "@webdoc/model";
DocType,
} from "@webdoc/types";

import type {ExplorerTarget} from './crawl-reference-explorer';

Expand All @@ -23,7 +23,7 @@ export type CategorizedDocumentList = {

export type CrawlData = {
index: { [id: string]: [] & { url: string } };
reference: ExplorerTarget;
reference: ?ExplorerTarget;
tutorials: ?ExplorerTarget;
};

Expand All @@ -34,11 +34,31 @@ declare function crawl(tree: RootDoc, index: string): CrawlData;
function crawl(tree /*: RootDoc */, index /*: string */)/*: CrawlData */ {
buildLinks(tree);

return {
const crawlData /*: CrawlData */ = {
index: buildIndex(tree),
reference: crawlReference(tree, index),
tutorials: crawlTutorials(tree),
};

if (crawlData.reference) {
// Add ClassIndex into explorer after (overview), while preserving order
// $FlowFixMe
crawlData.reference.children = Object.assign(...[
...crawlData.reference.children["(overview)"] ? [{
"(overview)": crawlData.reference.children["(overview)"],
}] : [],
...crawlData.index.classes.length > 0 ? [{
ClassIndex: {
title: "Class Index",
page: crawlData.index.classes.url,
},
}] : [], {
...crawlData.reference.children,
},
]);
}

return crawlData;
}

module.exports = ({crawl}/*: {crawl: typeof crawl} */);
Expand All @@ -57,15 +77,15 @@ function buildLinks(tree /*: RootDoc */) /*: void */ {
});
}

function buildIndex(tree /*: RootDoc */) /*: [id: string]: [] & { url: string } */ {
function buildIndex(
tree /*: RootDoc */,
)/*: { [string]: $ReadOnlyArray<Doc> & { url: string } } */ {
const classIndexUrl = linker.createURI("Class-Index", true);

const index /*: [id: string]: [] & { url: string } */ = {
classes: [],
const index /*: {[string]: Array<any> & {url: string}} */ = {
classes: Object.assign(([] /*: any */), {url: classIndexUrl}),
};

index.classes.url = classIndexUrl;

traverse(tree, (doc) => {
switch (doc.type) {
case "ClassDoc":
Expand Down
60 changes: 36 additions & 24 deletions packages/webdoc-default-template/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {
TemplateTagsResolver,
} = require("@webdoc/template-library");
const {linker} = require("./helper/linker");
const _ = require("lodash");

// Plugins
const {indexSorterPlugin} = require("./helper/renderer-plugins/index-sorter");
Expand All @@ -26,7 +27,7 @@ import type {
TutorialDoc,
} from "@webdoc/types";

import type {CrawlData} from './crawl';
import type {CrawlData} from './helper/crawl';

type AppBarItem = {
name: string;
Expand Down Expand Up @@ -66,25 +67,29 @@ exports.publish = async function publish(options /*: PublishOptions */) {

const docTree = options.documentTree;
const outDir = path.normalize(options.config.opts.destination);
const index = linker.createURI("index");
const indexRelative = index.replace(`/${linker.siteRoot}/`, "");
const index = config.template.readme ? linker.createURI("index") : null;
const indexRelative = index ? index.replace(`/${linker.siteRoot}/`, "") : null;

fse.ensureDir(outDir);

const crawlData = crawl(docTree, index);
const appBarItems = {
"reference": {
name: "API Reference",
uri: index,
},
const appBarItems = _.merge(config.template.appBar.items, {
/* NOTE: config.template.appBar.items is the primary object so we retain the order as the user
desires. */
...(crawlData.reference && {
"reference": {
name: "API Reference",
uri: index,
},
}),
...(crawlData.tutorials && {
"tutorials": {
name: "Tutorials",
uri: crawlData.tutorials.page ||
crawlData.tutorials.children[Object.keys(crawlData.tutorials.children)[0]].page,
},
}),
};
});
const renderer = new TemplateRenderer(path.join(__dirname, "tmpl"), null, docTree)
.setLayoutTemplate("layout.tmpl")
.installPlugin("linker", linker)
Expand Down Expand Up @@ -124,7 +129,7 @@ exports.publish = async function publish(options /*: PublishOptions */) {

await outStaticFiles(outDir, config);
outExplorerData(outDir, crawlData);
outMainPage(path.join(outDir, indexRelative), pipeline, options.config);
outMainPage(indexRelative ? path.join(outDir, indexRelative) : null, pipeline, options.config);
outIndexes(outDir, pipeline, options.config, crawlData.index);
outReference(outDir, pipeline, options.config, docTree);
outTutorials(outDir, pipeline, options.config, docTree);
Expand Down Expand Up @@ -204,11 +209,11 @@ function outExplorerData(outDir /*: string */, crawlData /*: CrawlData */) {

// Render the main-page into index.html (outputFile)
async function outMainPage(
outputFile /*: string */,
outputFile /*: ?string */,
pipeline /*: TemplatePipeline */,
config /*: WebdocConfig */,
) {
if (config.template.readme) {
if (outputFile && config.template.readme) {
const readmeFile = path.join(process.cwd(), config.template.readme);

outReadme(
Expand Down Expand Up @@ -262,18 +267,20 @@ function outIndexes(
"classes": "Class Index",
};

function outIndex(indexKey, indexList) {
const title = KEY_TO_TITLE[indexKey];
const url = linker.processInternalURI(indexList.url, {outputRelative: true});

pipeline.render("pages/api-index.tmpl", {
appBar: {current: "reference"},
documentList: indexList,
title,
env: config,
}, {
outputFile: path.join(outDir, url),
});
function outIndex(indexKey, indexList /*: Array<Doc> */) {
if (indexList.length > 0) {
const title = KEY_TO_TITLE[indexKey];
const url = linker.processInternalURI(indexList.url, {outputRelative: true});

pipeline.render("pages/api-index.tmpl", {
appBar: {current: "reference"},
documentList: indexList,
title,
env: config,
}, {
outputFile: path.join(outDir, url),
});
}
}

for (const [key, list] of Object.entries(index)) {
Expand All @@ -287,6 +294,11 @@ function outReference(
config /*: WebdocConfig */,
docTree /*: RootDoc */,
) {
// Don't output if nothing's there
if (!docTree.members.length) {
return;
}

for (const [id, docRecord] of linker.documentRegistry) {
let {uri: page} = docRecord;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ export default connect(({explorerOpen}) => ({
/>}
<div className="header__contents">
{items.map(([id, appBarItem], i) => (
<a
className={`header__link${id === currentItemId ? " header__link__current" : ""}`}
href={appBarItem.uri}
>
{appBarItem.name}
</a>
appBarItem.kind === "divider" ?
<section className={`header--divider header--item-${id}`}
dangerouslySetInnerHTML={{__html: appBarItem.content}}
/> :
<a
className={`header__link${id === currentItemId ? " header__link__current" : ""}`}
href={appBarItem.uri}
dangerouslySetInnerHTML={{__html: appBarItem.name}}
/>
))}
{appData.integrations.search && <Search integration={appData.integrations.search} />}
</div>
Expand Down
4 changes: 4 additions & 0 deletions packages/webdoc-default-template/src/styles/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
&__link {
color: black;
text-decoration: underline;

&:hover {
color: $colorPrimary;
}
}

&__link__current {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9698,10 +9698,18 @@ function Header_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
id = _ref4[0],
appBarItem = _ref4[1];

return React.createElement("a", {
return appBarItem.kind === "divider" ? React.createElement("section", {
className: "header--divider header--item-".concat(id),
dangerouslySetInnerHTML: {
__html: appBarItem.content
}
}) : React.createElement("a", {
className: "header__link".concat(id === currentItemId ? " header__link__current" : ""),
href: appBarItem.uri
}, appBarItem.name);
href: appBarItem.uri,
dangerouslySetInnerHTML: {
__html: appBarItem.name
}
});
}), appData.integrations.search && React.createElement(Search, {
integration: appData.integrations.search
})));
Expand Down
Loading