Open jamiebuilds opened 6 years ago
There’s JSON schema? I assume Microsoft is already trying to do this for a ‘package.json’ - so could build on that?
He means spec format, I vote for Markdown.
WebIDL is overkill for plain JSON values, Bikeshed looks great though!
Do any of the options have a way of generating JSON Schema?
Markdown is probably the easiest and is likely sufficient for what we're doing here. I don't have experience with the others though so not sure.
Once the spec has been parsed, it should be fairly easy to generate various outputs from it, as I attempt to do in this Observable notebook.
#### Rules\n\n*
to the last line)
To hack on or improve the parser, I’d suggest visiting [the online playground](https://pegjs.org/online) for PEG.js.
```js
{
function slugify(str) {
return str.toLowerCase().replace(/[^a-z]+/g, '-').replace(/^-|-$/g, '')
}
}
Spec
= title: H1
intro: Line '\n\n'
toc: (TOC '\n')+
'\n'
sections: Section+
{return {
title,
intro,
toc: toc.map(([line]) => line),
sections,
}}
TOC
= indent: ' '* [*-] ' [' label: $ [^\]]+ '](#' slug: $ [^)]+ ')'
{
if (slugify(label) !== slug) {
expected('slug to match label')
}
return {
indent: indent.length,
label,
id: slug
}
}
Section
= title: H2
keys: Key+
{return { title, keys }}
Key
= name: (
heading: H3
{
let name = heading.match(/^`(.+)`$/)
return name ? name[1] : expected('code literal inside heading')
}
)
meta: (
required: '**(Required)**'
{return { required: true }}
/ default_: '**(Default)**' Line
{return { required: false, default: default_ }}
)
[\n ]*
desc: Line
'\n\n'
'```json\n'
sample: $[^`]+
'```\n\n'
(h4: H4 { h4 === 'Rules' || expected('rules section header')})
rules: List
tips: (
'\n'
(h4: H4 { h4 === 'Tips' || expected('tips section header')})
tips: List
'\n'
{return tips}
)?
{
return { name, meta, desc, sample: sample.trimRight(), rules, tips: tips || [] }
}
List 'list' = ('* ' content: Line '\n' {return content})+
Line 'line of text' = $[^\n]+
H1 'h1' = '# ' content: Line '\n\n' {return content}
H2 'h2' = '#' content: H1 {return content}
H3 'h3' = '#' content: H2 {return content}
H4 'h4' = '#' content: H3 {return content}
```
I'm good with Markdown.
But I think we should break things down a bit better. It would be nice to have shared definitions of stuff like:
"major.minor.patch"
"^1.0.0 || >=2.0.0"
"valid-name123"
'name <email> (url)"
or { name?: string, email?: string, url?: string }
That way we can reference the same types over and over without having to repeat ourselves and potentially have inconsistencies.
Stuff like Bikeshed and Ecmarkup are good for this sort of thing because they generate links between everything and make it easy to reference stuff. Ecmarkup is markdown based too
It’s fairly simple to link type names to their definition; for example, this Observable notebook will convert inline code blocks written with the ``SemanticVersion``
syntax to a link to the “SemanticVersion
” header.
Yeah definitely want definitions like that. We could do links like [SemanticVersion](#SemanticVersion)
to go to that section. Github already generates ids for all headings so we wouldn't need to generate anything in order to read the spec.
@devongovett Check out the notebook — that’s exactly what it does 😉
An observable notebook is not a good format for a spec and we definitely should not use a custom tool for doing this.
SchemaStore has a schema for package.json
we could perhaps work off of.
How should we document everything?