Skip to content

Commit

Permalink
feat: added flag (--no-titles-in-links) to skip generating titles in …
Browse files Browse the repository at this point in the history
…links

Added flag (--no-titles-in-links) to skip generating titles in links as this is not supported by
jekyll and just-the-docs
  • Loading branch information
mickem committed Dec 19, 2022
1 parent d9ed260 commit e899a7c
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 19 deletions.
8 changes: 8 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export function jsonschema2md(schema, options) {
metadata,
schemaOut,
includeReadme,
skipTitles,
links,
i18n,
language,
Expand Down Expand Up @@ -159,6 +160,7 @@ export function jsonschema2md(schema, options) {
// build readme
readme({
readme: true,
skipTitles,
}),

writereadme({
Expand Down Expand Up @@ -195,6 +197,7 @@ export function jsonschema2md(schema, options) {
).split(nodepath.sep).join(nodepath.posix.sep);
return target;
},
skipTitles
}),

// write to files
Expand Down Expand Up @@ -260,6 +263,9 @@ export async function main(args) {
.alias('n', 'no-readme')
.describe('n', 'Do not generate a README.md file in the output directory')

.alias('t', 'no-titles-in-links')
.describe('t', 'Do not add titles to generated markdown links')

.describe('link-*', 'Add this file as a link the explain the * attribute, e.g. --link-abstract=abstract.md')

.alias('i', 'i18n')
Expand Down Expand Up @@ -303,6 +309,7 @@ export async function main(args) {
const metadata = argv.m;
const schemaOut = argv.x !== '-' ? argv.x : null;
const includeReadme = !argv.n;
const skipTitles = argv.t;
const i18n = argv.i;
const language = argv.l;
const exampleFormat = argv.f;
Expand Down Expand Up @@ -331,6 +338,7 @@ export async function main(args) {
metadata,
schemaOut,
includeReadme,
skipTitles,
links,
i18n,
language,
Expand Down
40 changes: 24 additions & 16 deletions lib/markdownBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function build({
links = {},
includeProperties = [],
rewritelinks = (x) => x,
skipTitles,
exampleFormat = 'json',
skipProperties = [],
} = {}) {
Expand Down Expand Up @@ -246,6 +247,13 @@ export default function build({
}
return [];
}
function makelink(url, title, description) {
if (skipTitles) {
return link(url, '', description);
} else {
return link(url, title, description);
}
}

/**
* Generates the overall header for the schema documentation
Expand All @@ -266,7 +274,7 @@ export default function build({
headerprops,
({ name, title }) => {
if (links[name]) {
return tableCell(link(links[name], i18n`What does ${title} mean?`, text(title)));
return tableCell(makelink(links[name], i18n`What does ${title} mean?`, text(title)));
}
return tableCell(text(title));
},
Expand All @@ -281,7 +289,7 @@ export default function build({
&& typeof schema[s.meta][prop.name] === 'object'
&& schema[s.meta][prop.name].link
&& schema[s.meta][prop.name].text) {
return tableCell(link(rewritelinks(schema[s.meta][prop.name].link), i18n`open original schema`, [text(schema[s.meta][prop.name].text)]));
return tableCell(makelink(rewritelinks(schema[s.meta][prop.name].link), i18n`open original schema`, [text(schema[s.meta][prop.name].text)]));
}
const value = schema[s.meta] ? schema[s.meta][prop.name] : undefined;
return tableCell(text(prop[`${String(value)}label`] || i18n`Unknown`));
Expand Down Expand Up @@ -323,11 +331,11 @@ export default function build({
*/
function makepropheader(required = [], ispattern = false, slugger) {
return ([name, definition]) => tableRow([
tableCell(ispattern ? inlineCode(name) : link(`#${slugger.slug(name)}`, '', text(name))), // Property
tableCell(ispattern ? inlineCode(name) : makelink(`#${slugger.slug(name)}`, '', text(name))), // Property
tableCell(type(definition)),
tableCell(text(required.indexOf(name) > -1 ? i18n`Required` : i18n`Optional`)),
tableCell(nullable(definition)),
tableCell(link(
tableCell(makelink(
`${definition[s.slug]}.md`,
`${definition[s.id]}#${definition[s.pointer]}`,
text(definition[s.titles] && definition[s.titles][0] ? definition[s.titles][0] : i18n`Untitled schema`),
Expand Down Expand Up @@ -358,7 +366,7 @@ export default function build({
tableCell(any ? text('Any') : type(additionalProps)),
tableCell(text(i18n`Optional`)),
tableCell(any ? text('can be null') : nullable(additionalProps)),
tableCell(any ? text('') : link(`${additionalProps[s.slug]}.md`, `${additionalProps[s.id]}#${additionalProps[s.pointer]}`, text(additionalProps[s.titles][0] || i18n`Untitled schema`))),
tableCell(any ? text('') : makelink(`${additionalProps[s.slug]}.md`, `${additionalProps[s.id]}#${additionalProps[s.pointer]}`, text(additionalProps[s.titles][0] || i18n`Untitled schema`))),
])];
}
return [];
Expand Down Expand Up @@ -388,7 +396,7 @@ export default function build({
paragraph([text(i18n`Type: `), text(i18n`an array where each item follows the corresponding schema in the following list:`)]),
list(
'ordered',
[...items.map((schema) => listItem(paragraph(link(
[...items.map((schema) => listItem(paragraph(makelink(
`${schema[s.slug]}.md`,
i18n`check type definition`,
text(gentitle(schema[s.titles], schema[keyword`type`])),
Expand All @@ -398,7 +406,7 @@ export default function build({
return [listItem(paragraph(text(i18n`and all following items may follow any schema`)))];
} else if (typeof additional === 'object') {
return [listItem(paragraph([text(i18n`and all following items must follow the schema: `),
link(
makelink(
`${additional[s.slug]}.md`,
i18n`check type definition`,
text(gentitle(additional[s.titles], additional[keyword`type`])),
Expand Down Expand Up @@ -448,9 +456,9 @@ export default function build({
const typelink = (() => {
if (definition[keyword`title`] && typeof definition[keyword`title`] === 'string') {
// if the type has a title, always create a link to the schema
return [text(' ('), link(`${definition[s.slug]}.md`, '', text(definition[keyword`title`])), text(')')];
return [text(' ('), makelink(`${definition[s.slug]}.md`, '', text(definition[keyword`title`])), text(')')];
} else if (!singletype || firsttype === keyword`object` || merged) {
return [text(' ('), link(`${definition[s.slug]}.md`, '', text(i18n`Details`)), text(')')];
return [text(' ('), makelink(`${definition[s.slug]}.md`, '', text(i18n`Details`)), text(')')];
}
return [];
})();
Expand All @@ -473,7 +481,7 @@ export default function build({
function makedefinedinfact(definition) {
return listItem(paragraph([
text(i18n`defined in: `),
link(`${definition[s.slug]}.md`, `${definition[s.id]}#${definition[s.pointer]}`, text(definition[s.titles] && definition[s.titles][0] ? definition[s.titles][0] : i18n`Untitled schema`)),
makelink(`${definition[s.slug]}.md`, `${definition[s.id]}#${definition[s.pointer]}`, text(definition[s.titles] && definition[s.titles][0] ? definition[s.titles][0] : i18n`Untitled schema`)),
]));
}

Expand Down Expand Up @@ -544,7 +552,7 @@ export default function build({
];
} else if (depth > 0) {
return [
link(`${schema[s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[s.titles], schema[keyword`type`]))),
makelink(`${schema[s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[s.titles], schema[keyword`type`]))),
];
} else {
return [];
Expand Down Expand Up @@ -621,15 +629,15 @@ export default function build({
// console.log('pattern!', schema[s.filename], schema[s.pointer]);
constraints.push(paragraph([strong(text(i18n`pattern`)), text(': '), text(i18n`the string must match the following regular expression: `)]));
constraints.push(code('regexp', schema[keyword`pattern`]));
constraints.push(paragraph([link(`https://regexr.com/?expression=${encodeURIComponent(schema[keyword`pattern`])}`, i18n`try regular expression with regexr.com`, text(i18n`try pattern`))]));
constraints.push(paragraph([makelink(`https://regexr.com/?expression=${encodeURIComponent(schema[keyword`pattern`])}`, i18n`try regular expression with regexr.com`, text(i18n`try pattern`))]));
}
// https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7.3
if (schema.format && typeof schema.format === 'string' && formats[schema.format]) {
constraints.push(paragraph([
strong(text(formats[keyword([schema.format])].label)),
text(': '),
text(formats[schema.format].text),
link(formats[schema.format].speclink, i18n`check the specification`, text(formats[schema.format].specname)),
makelink(formats[schema.format].speclink, i18n`check the specification`, text(formats[schema.format].specname)),
]));
} else if (schema.format && typeof schema.format === 'string') {
constraints.push(paragraph([strong(text(i18n`unknown format`)), text(': '), text(i18n`the value of this string must follow the format: `), inlineCode(String(schema.format))]));
Expand All @@ -645,7 +653,7 @@ export default function build({
constraints.push(paragraph([
strong(text(i18n`schema`)), text(': '),
text(i18n`the contents of this string should follow this schema: `),
link(`${schema[keyword`contentSchema`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contentSchema`][s.titles], schema[keyword`contentSchema`][keyword`type`])))]));
makelink(`${schema[keyword`contentSchema`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contentSchema`][s.titles], schema[keyword`contentSchema`][keyword`type`])))]));
}

// https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4
Expand All @@ -664,12 +672,12 @@ export default function build({
if (schema[keyword`minContains`] !== undefined && schema[keyword`contains`]) {
// console.log('minContains!', schema[s.filename], schema[s.pointer]);
constraints.push(paragraph([strong(text(i18n`minimum number of contained items`)), text(': '), text(`${i18n`this array may not contain fewer than ${String(schema[keyword`minContains`])} items that validate against the schema:`} `),
link(`${schema[keyword`contains`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contains`][s.titles], schema[keyword`contains`][keyword`type`])))]));
makelink(`${schema[keyword`contains`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contains`][s.titles], schema[keyword`contains`][keyword`type`])))]));
}
if (schema[keyword`maxContains`] !== undefined && schema[keyword`contains`]) {
// console.log('maxContains!', schema[s.filename], schema[s.pointer]);
constraints.push(paragraph([strong(text(i18n`maximum number of contained items`)), text(': '), text(`${i18n`this array may not contain more than ${String(schema[keyword`maxContains`])} items that validate against the schema:`} `),
link(`${schema[keyword`contains`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contains`][s.titles], schema[keyword`contains`][keyword`type`])))]));
makelink(`${schema[keyword`contains`][s.slug]}.md`, i18n`check type definition`, text(gentitle(schema[keyword`contains`][s.titles], schema[keyword`contains`][keyword`type`])))]));
}

// https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5
Expand Down
13 changes: 10 additions & 3 deletions lib/readmeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,23 @@ function makeversionnote(schemas) {
* Generate the README.md
* @param {object} opts
*/
export default function build({ readme = true }) {
export default function build({ readme = true, skipTitles = false }) {
return (schemas) => {
function makelink(url, title, description) {
if (skipTitles) {
return link(url, '', description);
} else {
return link(url, title, description);
}
}
if (readme) {
console.log('building readme');
const toplevel = flist(pipe(
schemas,
filter((schema) => !schema[s.parent]), // remove schemas with a parent
mapSort((schema) => gentitle(schema[s.titles], schema[keyword`type`])),
map((schema) => listItem(paragraph([
link(`./${schema[s.slug]}.md`, gendescription(schema), [text(gentitle(schema[s.titles], schema[keyword`type`]))]),
makelink(`./${schema[s.slug]}.md`, gendescription(schema), [text(gentitle(schema[s.titles], schema[keyword`type`]))]),
text(' – '),
inlineCode(schema[keyword`$id`] || '-'),
]))),
Expand All @@ -65,7 +72,7 @@ export default function build({ readme = true }) {
filter((schema) => !schema.$ref), // it is not a reference
mapSort((schema) => gentitle(schema[s.titles], schema[keyword`type`])),
map((schema) => listItem(paragraph([
link(`./${schema[s.slug]}.md`, gendescription(schema), [text(gentitle(schema[s.titles], schema[keyword`type`]))]),
makelink(`./${schema[s.slug]}.md`, gendescription(schema), [text(gentitle(schema[s.titles], schema[keyword`type`]))]),
text(' – '),
inlineCode(`${schema[s.id]}#${schema[s.pointer]}`),
]))),
Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/skiptitles/complete.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Complete JSON Schema",
"description": "Testing for skipped props",
"type": "object",
"properties": {
"foo": {
"type": "string"
}
}
}
17 changes: 17 additions & 0 deletions test/markdownBuilder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,23 @@ value: Maximum
});
});

describe('Testing Markdown Builder: Skip titles', () => {
let results;

before(async () => {
const schemas = await traverseSchemas('skiptitles');
const builder = build({ header: false, skipTitles: true });
results = builder(schemas);
});

it('Format Schema has JSON examples', () => {
console.log(results.complete)
assertMarkdown(results.complete)
.contains('[Complete JSON Schema](complete-properties-foo.md)')
.doesNotContain('[Complete JSON Schema](complete-properties-foo.md "undefined#/properties/foo")');
});
});

describe('Testing Markdown Builder: enums', () => {
let results;

Expand Down
31 changes: 31 additions & 0 deletions test/readmeBuilder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ describe('Testing Readme Builder', () => {
assertMarkdown(result)
.contains('# README')
.matches(/Top-level Schemas/)
.contains('[Test Schema](./example.md "Not much")')
.has('heading > text')
.equals('heading > text', {
type: 'text',
Expand All @@ -103,4 +104,34 @@ describe('Testing Readme Builder', () => {
### Arrays`;
});
it('Readme Builder should skip titles in links if flag is set', () => {
const builder = build({ readme: true, skipTitles: true });
const schemaloader = loader();
const schemas = [
schemaloader('example.schema.json', {
type: 'object',
title: 'Test Schema',
description: 'Not much',
properties: {
foo: {
const: 1,
},
obj: {
type: 'object',
title: 'An Object',
},
arr: {
type: 'array',
title: 'An Array',
},
},
}),
];

const result = builder(schemas);
// eslint-disable-next-line no-unused-expressions
assertMarkdown(result)
.contains('[Test Schema](./example.md)')
.doesNotContain('[Test Schema](./example.md "Not much")');
});
});

0 comments on commit e899a7c

Please sign in to comment.