Skip to content

Commit

Permalink
feat(i18n): enable localization of all strings, provide en as default…
Browse files Browse the repository at this point in the history
… language


fixes #143
  • Loading branch information
Claymore1337 authored and trieloff committed Jul 30, 2019
1 parent d4fb87c commit daa58a2
Show file tree
Hide file tree
Showing 28 changed files with 642 additions and 191 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ $ jsonschema2md -d examples/schemas -o examples/docs -v 04
$ jsonschema2md -d examples/schemas -o examples/docs -v 06
```

## Text in Templates
Each text which is not provided by the JSON Schema is loaded from an i18n file. With i18n parameter you can change the location of the i18n folder and load your own text file. The folder must contain an locales folder and in this folder there should be an en.json file.

```bash
# run against JSON Schema Draft 06
$ jsonschema2md -d examples/schemas -o examples/docs -v 06 -i temp/myFiles
```




## Using JSON Schema Markdown Tools from `npm`

You can conveniently use the JSON Schema Markdown Tools from `npm`. This makes it possible to set up a conversion toolchain for your JSON Schema project that is driven entirely by `npm`. To do so, first define the dependency by adding this to your `"devDependencies"` section of `package.json`
Expand Down
6 changes: 4 additions & 2 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ var argv = require('optimist')
throw 'Meta schema file "' + args.s + '" does not exist!';
}
})
.alias('i', 'i18n')
.describe('i', 'path to a locales folder with an en.json file in it. This file will be used for all text parts in all templates')
.argv;

const docs = _.fromPairs(_.toPairs(argv).filter(([ key, value ]) => { return key.startsWith('link-'); }).map(([ key, value ]) => { return [ key.substr(5), value ];}));
Expand Down Expand Up @@ -122,7 +124,7 @@ if (target.isDirectory()) {
return Promise.reduce(files, readSchemaFile, schemaPathMap)
.then(schemaMap => {
logger.info('finished reading all *.%s files in %s, beginning processing….', schemaExtension, schemaPath);
return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, readme, docs);
return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, readme, docs, argv);
})
.then(() => {
logger.info('Processing complete.');
Expand All @@ -143,7 +145,7 @@ if (target.isDirectory()) {
Schema.setAjv(ajv);
Schema.setSchemaPathMap(schemaPathMap);
logger.info('finished reading %s, beginning processing....', schemaPath);
return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, false, docs);
return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, false, docs, argv);
})
.then(() => {
logger.info('Processing complete.');
Expand Down
24 changes: 13 additions & 11 deletions lib/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const _ = require('lodash');
const i18n = require('i18n');
const path = require('path');

function custom(schema) {
Expand All @@ -22,11 +23,12 @@ function custom(schema) {
function schemaProps(schema, schemaPath, filename) {
return {
// if there are definitions, but no properties
abstract: (schema.definitions !== undefined && _.keys(schema.properties).length === 0) ? 'Cannot be instantiated' : 'Can be instantiated',
extensible: (schema.definitions !== undefined || schema['meta:extensible'] === true) ? 'Yes' : 'No',
status: schema['meta:status'] !== undefined ? (schema['meta:status'].charAt(0).toUpperCase() + schema['meta:status'].slice(1)) : 'Experimental',
custom: custom(schema) ? 'Allowed' : 'Forbidden',
abstract: (schema.definitions !== undefined && _.keys(schema.properties).length === 0) ? i18n.__('header.tabel.abstractNo') : i18n.__('header.tabel.abstractYes'),
extensible: (schema.definitions !== undefined || schema['meta:extensible'] === true) ? i18n.__('header.tabel.extensibleYes') : i18n.__('header.tabel.extensibleNo'),
status: schema['meta:status'] !== undefined ? (schema['meta:status'].charAt(0).toUpperCase() + schema['meta:status'].slice(1)) : i18n.__('header.tabel.statusExperimental'),
custom: custom(schema) ? i18n.__('header.tabel.customPropertiesYes') : i18n.__('header.tabel.customPropertiesNo'),
original: filename.substr(schemaPath.length).substr(1),
additionalProperties:schema.additionalProperties===false ? i18n.__('header.tabel.additionalPropertiesNo'): i18n.__('header.tabel.additionalPropertiesYes'),
};
}

Expand Down Expand Up @@ -99,13 +101,13 @@ function headers(schema, indir, filename, docs, outdir) {
this.doclinks = docs ? docs : {};
this.myheaders = [];

this.myheaders.push(new Header('Abstract', link(indir, filename, this.doclinks['abstract']), props.abstract));
this.myheaders.push(new Header('Extensible', link(indir, filename, this.doclinks['extensible']), props.extensible));
this.myheaders.push(new Header('Status', link(indir, filename, this.doclinks['status']), props.status));
this.myheaders.push(new Header('Identifiable', link(indir, filename, this.doclinks['id']), isIdentifiable(schema)));
this.myheaders.push(new Header('Custom Properties', link(indir, filename, this.doclinks['custom']), props.custom));
this.myheaders.push(new Header('Additional Properties', link(indir, filename, this.doclinks['additional']), schema.additionalProperties===false ? 'Forbidden' : 'Permitted'));
this.myheaders.push(new Header('Defined In', undefined, props.original, path.basename(props.original)));
this.myheaders.push(new Header(i18n.__('header.tabel.abstract'), link(indir, filename, this.doclinks['abstract']), props.abstract));
this.myheaders.push(new Header(i18n.__('header.tabel.extensible'), link(indir, filename, this.doclinks['extensible']), props.extensible));
this.myheaders.push(new Header(i18n.__('header.tabel.status'), link(indir, filename, this.doclinks['status']), props.status));
this.myheaders.push(new Header(i18n.__('header.tabel.identifiable'), link(indir, filename, this.doclinks['id']), isIdentifiable(schema)));
this.myheaders.push(new Header(i18n.__('header.tabel.customProperties'), link(indir, filename, this.doclinks['custom']), props.custom));
this.myheaders.push(new Header(i18n.__('header.tabel.additionalProperties'), link(indir, filename, this.doclinks['additional']), props.additionalProperties));
this.myheaders.push(new Header(i18n.__('header.tabel.definedIn'), undefined, props.original, path.basename(props.original)));

this.render = function() {
var buf = '';
Expand Down
171 changes: 171 additions & 0 deletions lib/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
{
"header.titel": "Schema",
"header.hierarchy": "Schema Hierarchy",
"header.tabel.abstract": "Abstract",
"header.tabel.abstractYes": "Can be instantiated",
"header.tabel.abstractNo": "Cannot be instantiated",
"header.tabel.extensible": "Extensible",
"header.tabel.extensibleYes": "Yes",
"header.tabel.extensibleNo": "No",
"header.tabel.status": "Status",
"header.tabel.statusExperimental": "Experimental",
"header.tabel.identifiable": "Identifiable",
"header.tabel.customProperties": "Custom Properties",
"header.tabel.customPropertiesYes": "Allowed",
"header.tabel.customPropertiesNo": "Forbidden",
"header.tabel.additionalProperties": "Additional Properties",
"header.tabel.additionalPropertiesYes": "Permitted",
"header.tabel.additionalPropertiesNo": "Forbidden",
"header.tabel.definedIn": "Defined In",
"examples.example": "Example",
"examples.examples": "Examples",
"definitions.definitions": "Definitions",
"definitions.tabel.property": "Property",
"definitions.tabel.type": "Type",
"definitions.tabel.group": "Group",
"propertyIs": "is",
"propertyRequired": "**required**",
"propertyOptional": "optional",
"propertyType": "type:",
"propertyNestedArray": "(nested array)",
"propertyBetween": "between",
"propertyBetweenAnd": "and",
"propertyBetweenItems": "items in the array",
"propertyBetweenMaxItemsPrefix": "no more than",
"propertyBetweenMaxItemsSuffix": "items in the array",
"propertyBetweenMinItemsPrefix": "at least",
"propertyBetweenMinItemsSuffix": "items in the array",
"propertySchemaDefault": "default",
"propertySchemaDefinedIn": "defined in",
"propertySchemaDefinedSelf": "this schema",
"propertySchemaConst": "The value of this property **must** be equal to:",
"propertySchemaEnum": "The value of this property **must** be equal to one of the [known values below](#{{enum}}-known-values).",
"propertyHeaderType": "Type",
"propertyUnknownType": "Unknown type",
"propertyEnumKnownVaules": "Known Values",
"propertyEnum.tabel.value": "Value",
"propertyEnum.tabel.description": "Description",
"propertyExample": "Example",
"propertyExamples": "Examples",
"arrayTypeNested": "Nested array type:",
"arrayTypeArray": "Array type:",
"arrayTypeList": "All items must be of the type:",
"arrayTypeUnknownType": "Unknown type",
"booleanTypeNullabel": ", nullable",
"booleanTypeEmpty": " ",
"multitpleType.types": "Either one of:",
"multitpleType.none": "or `null`",
"joinTypeAny": "**Any** following *options* needs to be fulfilled.",
"joinTypeAll": "**All** of the following *requirements* need to be fulfilled.",
"joinTypeOne": "**One** of the following *conditions* need to be fulfilled.",
"joinTypeOption": "Option",
"joinTypeRequirement": "Requirement",
"joinTypeCondition": "Condition",
"innerSchemaDefined": "**Defined In:**",
"nestedProperties.tabel.property": "Property",
"nestedProperties.tabel.type": "Type",
"nestedProperties.tabel.required": "Required",
"nestedProperties.tabel.requiredYes": "**Required**",
"nestedProperties.tabel.requiredNo": "Optional",
"nestedProperties.tabel.default": "Default",
"nestedPropertyIs": "is",
"nestedPropertyRequired": "**required**",
"nestedPropertyOptinal": "optional",
"nestedPropertyType": "type:",
"nestedPropertyTypeNestedArray": "nested array",
"nestedPropertyItemsBetween": "between",
"nestedPropertyItemsAnd": "and",
"nestedPropertyItemsBetweenEnd": "items in the array",
"nestedPropertyItemsMax": "no more than",
"nestedPropertyItemsMaxEnd": "items in the array",
"nestedPropertyItemsMin": "at least",
"nestedPropertyItemsMinEnd": "items in the array",
"nestedPropertySchemaDefault": "default:",
"nestedPropertySchemaConst": "The value of this property **must** be equal to:",
"nestedPropertyHeaderType": "Type",
"nestedPropertyUnknownType": "Unknown type",
"nestedPropertySchemaEnum": "The value of this property **must** be equal to one of the [known values below](#{{enum}}-known-values).",
"nestedPropertyEnumKnownVaules": "Known Values",
"nestedPropertyEnum.tabel.value": "Value",
"nestedPropertyEnum.tabel.description": "Description",
"nestedPropertyExample": "Example",
"nestedPropertyExamples": "Examples",
"numberTypeExclusiveMinumum": "value must not be smaller or equal than:",
"numberTypeMinimum": "minimum value:",
"numberTypeExclusiveMaximum": "value must not be greater or equal than:",
"numberTypeMaximum": "maximum value:",
"numberTypeMultipleOf": "must be a multiple of",
"objectTypeObject": "object",
"objectTypeObjectFollowing": "with following properties:",
"patternPropertyPattern": "Pattern:",
"patternPropertyExpression": "Applies to all properties that match the regular expression",
"patternPropertyIsPropertyPattern": "is a property pattern",
"patternPropertyType": "type:",
"patternPropertyNestedArray": "(nested array):",
"patternPropertyBetween": "between",
"patternPropertyBetweenAnd": "and",
"patternPropertyBetweenItems": "items in the array",
"patternPropertyMaxItemsPrefix": "no more than",
"patternPropertyMaxItemsSuffix": "items in the array",
"patternPropertyMinItemsPrefix": "at least",
"patternPropertyMinItemsSuffix": "items in the array",
"patternPropertySchemaDefault": "default:",
"patternPropertySchemaDefinedIn": "defined in",
"patternPropertySchemaDefinedSelf": "this schema",
"patternPropertySchemaConst": "The value of this property **must** be equal to:",
"patternPropertySchemaEnum": "The value of this property **must** be equal to one of the [known values below](#{{enum}}-known-values).",
"patternPropertyHeaderPattern": "Pattern",
"patternPropertyHeaderType": "Type",
"patternPropertyUnknownType": "Unknown type",
"patternPropertyEnumPattern": "Pattern",
"patternPropertyEnumKnownVaules": "Known Values",
"patternPropertyEnum.tabel.value": "Value",
"patternPropertyEnum.tabel.description": "Description",
"patternPropertyExample": "Example",
"patternPropertyPatternExamples": "Pattern",
"patternPropertyExamples": "Examples",
"propertiesTitel": "Properties",
"properties.tabel.property": "Property",
"properties.tabel.type": "Type",
"properties.tabel.required": "Required",
"properties.tabel.nullable": "Nullable",
"properties.tabel.default": "Default",
"properties.tabel.definedBy": "Defined by",
"propertiesRequired": "**Required**",
"propertiesOptional": "Optional",
"propertiesNullableYes": "Yes",
"propertiesNullableNo": "No",
"propertiesSchema": "(this schema)",
"propertiesPattern": "Pattern",
"propertiesAny": "any",
"propertiesAdditional": "Additional",
"propertiesAdditionalYes": "Yes",
"propertiesPatternAdditionalText": "this schema *allows* additional properties",
"readmeHead": "Readme",
"stringTypeUri": "format: `uri` – Uniformous Resource Identifier (according to [RFC3986](http://tools.ietf.org/html/rfc3986))",
"stringTypeDateTime": "format: `date-time` – date and time (according to [RFC 3339, section 5.6](http://tools.ietf.org/html/rfc3339))",
"stringTypeEmail": "format: `email` – email address (according to [RFC 5322, section 3.4.1](https://tools.ietf.org/html/rfc5322))",
"stringTypeIPv4": "format: `ipv4` – IP (v4) address (according to [RFC 2673, section 3.2](https://tools.ietf.org/html/rfc2673))",
"stringTypeIPv6": "format: `ipv6` – IP (v6) address (according to [RFC 4291, section 2.2](https://tools.ietf.org/html/rfc4291))",
"stringTypeDate": "format: `date` – date, without time (according to [RFC 3339, section 5.6](http://tools.ietf.org/html/rfc3339))",
"stringTypeTime": "format: `time` – time, without date (according to [RFC 3339, section 5.6](http://tools.ietf.org/html/rfc3339))",
"stringTypeIdnEmail": "format: `idn-email` – international email address (according to [RFC 6531](https://tools.ietf.org/html/rfc6531))",
"stringTypeIdnHostname": "format: `idn-hostname` – Internationalized Domain Name (according to [RFC 5890, section 2.3.2.3](https://tools.ietf.org/html/rfc5890))",
"stringTypeUriReference": "format: `uri-reference` – URI Reference (according to [RFC3986](https://tools.ietf.org/html/rfc3986))",
"stringTypeIRI": "format: `iri` – Internationalized Resource Identifier (according to [RFC3987](https://tools.ietf.org/html/rfc3987))",
"stringTypeIRIReference": "format: `iri-reference` – IRI Reference (according to [RFC3987](https://tools.ietf.org/html/rfc3987))",
"stringTypeURITemplate": "format: `uri-template` – URI Template (according to [RFC6570](https://tools.ietf.org/html/rfc6570))",
"stringTypeJSONPointer": "format: `json-pointer` – JSON Pointer (according to [RFC 6901, section 5](https://tools.ietf.org/html/rfc6901))",
"stringTypeRegex": "format: `regex` – Regular Expression (according to [ECMA 262](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf))",
"stringTypeRelativeJsonPointer": "format: `relative-json-pointer` – Relative JSON Pointer (according to [Relative JSON Pointer](http://tools.ietf.org/html/draft-handrews-relative-json-pointer-00))",
"stringTypeHostname": "format: `hostname` – Domain Name (according to [RFC 1034, section 3.1](https://tools.ietf.org/html/rfc1034))",
"stringTypeMinimum": "minimum length:",
"stringTypeMinimumCharacters": "characters",
"stringTypeMaximum": "maximum length:",
"stringTypeMaximumCharacters": "characters",
"stringTypePattern": "All instances must conform to this regular expression ",
"stringTypePatternExampleUndefined": "(test examples [here](https://regexr.com/?expression={{pattern}} )):",
"stringTypePatternExampleString": "((test example: [{{example}}](https://regexr.com/?expression={{pattern}}&text={{text}})):",
"stringTypePatternExampleNotString": "* test example: [{{example}}](https://regexr.com/?expression={{pattern}}&text={{text}})",
"nullType": "This property can only have the value `null`."
}
Loading

0 comments on commit daa58a2

Please sign in to comment.