Commit 1d14f898 authored by Christophe Benz's avatar Christophe Benz

First commit

parents
node_modules
# Table schema to Markdown
Generate Markdown documentation from a [table schema](https://frictionlessdata.io/specs/table-schema/) JSON file.
## Dependencies
```bash
npm install
```
## Usage
Given a table schema named `schema.json` (e.g. [this one](https://git.opendatafrance.net/scdl/subventions/blob/master/schema.json)):
```bash
node index.js --locale=fr /path/to/schema.json templates/fr/index.hbs
```
const fs = require("fs");
const path = require("path");
const argv = require("minimist")(process.argv.slice(2));
const areIntlLocalesSupported = require("intl-locales-supported");
const handlebars = require("handlebars");
const { get } = require("lodash");
const { Schema } = require("tableschema");
const translations = require("./translations.json");
// Load handlebars-helpers.
require("handlebars-helpers")({ handlebars });
function setupIntlPolyfill(localesMyAppSupports) {
if (global.Intl) {
// Determine if the built-in `Intl` has the locale data we need.
if (!areIntlLocalesSupported(localesMyAppSupports)) {
// `Intl` exists, but it doesn't have the data we need, so load the
// polyfill and patch the constructors we need with the polyfill's.
var IntlPolyfill = require("intl");
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
}
} else {
// No `Intl`, so use and load the polyfill.
global.Intl = require("intl");
}
}
const defaultLocale = "en-US";
const locale = argv.locale || defaultLocale;
setupIntlPolyfill([locale]);
// Load handlebars-intl after applying Intl polyfill.
const HandlebarsIntl = require("handlebars-intl");
HandlebarsIntl.registerWith(handlebars);
function transformField(field) {
const format = get(
translations.format,
`${locale}.${field.format}`,
field.format
);
const type = get(translations.type, `${locale}.${field.type}`, field.type);
return { ...field, format, type };
}
function transformSchema(schema, locale) {
const fields = schema.fields.map(transformField);
return { ...schema, fields };
}
async function main() {
// Process file arguments.
const schemaFilePath = path.resolve(argv._[0]);
const templateFilePath = path.resolve(argv._[1]);
let schema = await Schema.load(schemaFilePath, { strict: true });
let schemaJson = require(schemaFilePath);
schema = { ...schemaJson, ...schema.descriptor };
schema = transformSchema(schema, locale);
const templateSource = fs.readFileSync(templateFilePath).toString();
// Register partials.
const partialsDir = path.resolve(templateFilePath, "..", "partials");
fs.readdirSync(partialsDir).forEach(partialFileName => {
const partialFilePath = path.resolve(partialsDir, partialFileName);
const partialSource = fs.readFileSync(partialFilePath).toString();
const partialName = path.basename(
partialFilePath,
path.extname(partialFilePath)
);
handlebars.registerPartial(partialName, partialSource);
});
const template = handlebars.compile(templateSource);
const intlData = { locales: locale };
const output = template(schema, { data: { intl: intlData } });
console.log(output);
}
main().catch(error => {
console.error(error);
process.exit(1);
});
This diff is collapsed.
{
"name": "table-schema-to-markdown",
"version": "0.0.1",
"description": "Generate Markdown documentation from a \"table schema\" file",
"main": "index.js",
"bin": {
"table-schema-to-markdown": "./index.js"
},
"repository": {
"type": "git",
"url": "https://framagit.org/jailbreak/table-schema-to-markdown.git"
},
"keywords": [
"table-schema",
"markdown",
"doc"
],
"author": "Christophe Benz <christophe.benz@jailbreak.paris>",
"license": "MIT",
"dependencies": {
"handlebars": "^4.1.0",
"handlebars-helpers": "^0.10.0",
"handlebars-intl": "^1.1.2",
"hbs-cli": "^1.3.0",
"intl": "^1.2.5",
"intl-locales-supported": "^1.0.0",
"lodash": "^4.17.11",
"tableschema": "^1.9.1"
}
}
# {{{title}}}
{{{description}}}
## Version {{version}}
- Auteur : {{{author}}}
- Contributeurs : {{{contributor}}}
- Schéma créé le : {{formatDate created}}
- Schéma mis à jour le : {{formatDate updated}}
- Site web : {{{homepage}}}
{{#if missing_values}}
- Valeurs manquantes : {{join missing_values}}
{{/if}}
## Modèle de données
Ce modèle de données repose sur les {{formatNumber fields.length}} champs suivants correspondant aux colonnes du fichier
tabulaire.
{{> fieldsAsTitles }}
\ No newline at end of file
| nom | titre | description | type |
|-|-|-|-|
{{#each fields}}
|`{{{name}}}`|{{{title}}}|{{{description}}}|{{type}}|
{{/each}}
\ No newline at end of file
{{#each fields}}
### `{{{name}}}`
- Titre : {{{title}}}
- Description : {{{description}}}
- Type : {{formatMessage type}}{{#isnt format "default"}} ({{format}}){{/isnt}}
{{#if decimalChar}}
- Séparateur décimal : {{decimalChar}}
{{/if}}
{{#if groupChar}}
- Séparateur de groupes de chiffres : {{groupChar}}
{{/if}}
{{#if trueValues}}
- Valeurs considérées comme vraies : {{join trueValues}}
{{/if}}
{{#if falseValues}}
- Valeurs considérées comme fausses : {{join falseValues}}
{{/if}}
{{#if bareNumber}}
- Le nombre peut contenir des caractères supplémentaires (« € », « % » ...)
{{/if}}
{{#if rdfType}}
- Type RDF : {{rdfType}}
{{/if}}
{{#if example}}
- Exemple : "{{example}}"
{{/if}}
{{#if constraints.required}}
- Valeur obligatoire
{{else}}
- Valeur optionnelle
{{/if}}
{{#if constraints.unique}}
- Valeur unique
{{/if}}
{{#if constraints.minLength}}
- Taille minimale : {{formatNumber constraints.minLength}}
{{/if}}
{{#if constraints.maxLength}}
- Taille maximale : {{formatNumber constraints.maxLength}}
{{/if}}
{{#if constraints.minimum}}
- Valeur minimale : {{formatNumber constraints.minimum}}
{{/if}}
{{#if constraints.maximum}}
- Valeur maximale : {{formatNumber constraints.maximum}}
{{/if}}
{{#if constraints.pattern}}
- Motif : {{constraints.pattern}}
{{/if}}
{{#if constraints.enum}}
- Valeurs autorisées : {{join (map constraints.enum quote)}}
{{/if}}
{{/each}}
\ No newline at end of file
{
"fr": {
"type": {
"array": "liste",
"boolean": "booléen",
"date": "date",
"datetime": "date et heure",
"duration": "durée",
"geopoint": "point géographique",
"integer": "nombre entier",
"number": "nombre réel",
"object": "objet",
"string": "chaîne de caractères",
"time": "heure",
"year": "année",
"year-month": "année et mois"
},
"format": {
"email": "adresse de courriel",
"uri": "adresse URL",
"binary": "données binaires encodées en base64",
"uuid": "identifiant unique UUID"
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment