json shredder/extract handling

style guide docs for makeJson
remove dups in git-changed-examples
support for git-changed-examples --after
file pattern exclusion for git-changed-examples
This commit is contained in:
Jay Traband 2015-09-12 00:28:01 -07:00
parent bdb97ed499
commit a9e96389c0
17 changed files with 441 additions and 183 deletions

View File

@ -7,6 +7,8 @@ var del = require('del');
var _ = require('lodash');
var Git = require("nodegit");
var argv = require('yargs').argv;
var Q = require("q");
var Minimatch = require("minimatch").Minimatch;
var docShredder = require('./public/doc-shredder/doc-shredder');
@ -16,76 +18,10 @@ var _shredOptions = {
fragmentsDir: "_fragments"
};
// TODO: 'extractFragment' will be moved into _utilFns in the next release.
var _excludePatterns = ["**/node_modules/**", "**/typings/**"];
// Extract a subset of a json file in a specified order defined
// by extractPaths while retaining original order for any
// unspecified subobjects.
//
// based on the principle that JSON.parse(source) constructs objects
// in order from the top down in 'source' and JSON.stringify(source) iterates 'source'
// properties according to the order in which they were inserted. ( the spec actually
// discourages this assumption but this method will only
// run on node (v8) and the assumption seems safe there. )
function extractFragment(source, rootPath, extractPaths, space) {
var objSource = JSON.parse(source);
if (rootPath && rootPath.length > 0) {
objSource = getSubObject(objSource, rootPath);
}
var objDest = {};
extractPaths.trim().split(",").forEach(function(dotPath) {
processPath(objSource, objDest, dotPath );
});
var result = JSON.stringify(objDest, null, space);
return result;
function getSubObject(source, path) {
var nextSource = source;
var pathParts = path.trim().split(".");
while (pathParts.length > 0) {
var nextProp = pathParts.shift();
nextSource = nextSource[nextProp];
}
return nextSource;
}
function processPath(source, dest, dotPath) {
var nextSource = source;
var nextDest = dest;
var pathParts = dotPath.trim().split(".");
while (pathParts.length > 0) {
var nextProp = pathParts.shift();
nextSource = nextSource[nextProp];
if (pathParts.length > 0) {
var val = nextDest[nextProp] || {};
nextDest[nextProp] = val;
nextDest = val;
} else {
nextDest[nextProp] = nextSource;
}
}
}
}
// TODO: will be moved into _utilFns in the next release.
gulp.task('test-extract-fragments', function() {
var json = '{ ' +
'"foo": "foo value", ' +
'"bar": 3, ' +
'"x": {' +
' "y": {' +
' "y3": "zzz", ' +
' "y1": true, ' +
' "y2": 7 ' +
' }, ' +
' "cat": "z value", ' +
' "dog": "exclude" ' +
'} ' +
"}";
var f1 = extractFragment( json, null, "x.y, x.cat, foo", 2);
var f2 = extractFragment( json, "x" , "y.y2, y.y1", 2);
var _excludeMatchers = _excludePatterns.map(function(excludePattern){
return new Minimatch(excludePattern)
});
/*
@ -135,30 +71,148 @@ gulp.task('build-shred-maps', ['shred-full'], function() {
return buildShredMaps(true);
});
// Called with an sha parameter - like this
// gulp git-changed-examples --sha 4d2ac96fa247306ddd2d4c4e0c8dee2223502eb2
gulp.task('git-changed-examples', function(){
gulp.task('git-changed-examples', ['shred-full'], function(){
var after, sha, messageSuffix;
if (argv.after) {
try {
after = new Date(argv.after);
messageSuffix = ' after: ' + argv.after;
} catch (e) {
throw argv.after + " is not a valid date.";
}
} else if (argv.sha) {
sha = argv.sha;
messageSuffix = ' on commit: ' + (argv.sha.length ? argv.sha : '[last commit]');
} else {
console.log('git-changed-examples may be called with either an "--sha" argument like this:');
console.log(' gulp git-changed-examples --sha=4d2ac96fa247306ddd2d4c4e0c8dee2223502eb2');
console.log('or with an "--after" argument like this')
console.log(' gulp git-changed-examples --after="August 1, 2015"');
return;
}
var jadeShredMap;
return buildShredMaps(false).then(function(docs) {
jadeShredMap = docs[0];
// return getChangedExamples('7e6ff558e35fce3b6df45c66c43514c72fbf69e0 ').then(function(filePaths) {
return getChangedExamples(argv.sha);
if (after) {
return getChangedExamplesAfter(after);
} else if (sha) {
return getChangedExamples(sha);
} else {
console.log('git-changed-examples may be called with either an "--sha" argument like this:');
console.log(' gulp git-changed-examples --sha=4d2ac96fa247306ddd2d4c4e0c8dee2223502eb2');
console.log('or with an "--after" argument like this')
console.log(' gulp git-changed-examples --after="August 1, 2015"');
}
}).then(function(examplePaths) {
console.log('Examples changed on commit: ' + (argv.sha ? argv.sha : '[last commit]'));
examplePaths = filterOutExcludedPatterns(examplePaths, _excludeMatchers);
console.log('\nExamples changed ' + messageSuffix);
console.log(examplePaths)
console.log("Jade files and associated changed example files")
console.log("\nJade files and associated changed example files " + messageSuffix);
var jadeExampleMap = jadeShredMapToJadeExampleMap(jadeShredMap, examplePaths);
console.log(JSON.stringify(jadeExampleMap, null, " "));
console.log("-----");
}).catch(function(err) {
throw err;
});
});
//gulp.task('git-review-jade', function() {
//
//});
function filterOutExcludedPatterns(fileNames, excludeMatchers) {
return fileNames.filter(function(fileName) {
return !excludeMatchers.some(function(excludeMatcher) {
return excludeMatcher.match(fileName);
});
});
}
function buildShredMaps(shouldWrite) {
var options = _.extend(_shredOptions, {
jadeDir: '.',
outputDir: '.',
writeFilesEnabled: shouldWrite
});
return docShredder.buildShredMap(options).then(function(docs) {
return docs;
});
}
// returns a promise containing filePaths with any changed or added examples;
function getChangedExamples(sha) {
var examplesPath = path.join(_shredOptions.basePath, _shredOptions.examplesDir);
var relativePath = path.relative(process.cwd(), examplesPath);
return Git.Repository.open(".").then(function(repo) {
if (sha.length) {
return repo.getCommit(sha);
} else {
return repo.getHeadCommit();
}
}).then(function(commit) {
return getChangedExamplesForCommit(commit, relativePath);
}).catch(function(err) {
});
}
function getChangedExamplesAfter(date, relativePath) {
var examplesPath = path.join(_shredOptions.basePath, _shredOptions.examplesDir);
var relativePath = path.relative(process.cwd(), examplesPath);
return Git.Repository.open(".").then(function(repo) {
return repo.getHeadCommit();
}).then(function(commit) {
var repo = commit.owner();
var revWalker = repo.createRevWalk();
revWalker.sorting(Git.Revwalk.SORT.TIME);
revWalker.push(commit.id());
return revWalker.getCommitsUntil(function (commit) {
return commit.date().getTime() > date.getTime();
});
}).then(function(commits) {
return Q.all(commits.map(function(commit) {
return getChangedExamplesForCommit(commit, relativePath);
}));
}).then(function(arrayOfPaths) {
var pathMap = {};
arrayOfPaths.forEach(function(paths) {
paths.forEach(function(path) {
pathMap[path] = true;
});
});
var uniqPaths = _.keys(pathMap);
return uniqPaths;
}).catch(function(err) {
var x = err;
});
}
function getChangedExamplesForCommit(commit, relativePath) {
return commit.getDiff().then(function(diffList) {
var filePaths = [];
diffList.forEach(function (diff) {
diff.patches().forEach(function (patch) {
if (patch.isAdded() || patch.isModified) {
var filePath = path.normalize(patch.newFile().path());
var isExample = filePath.indexOf(relativePath) >= 0;
// console.log(filePath + " isExample: " + isExample);
if (isExample) {
filePaths.push(filePath);
}
}
});
});
return filePaths;
});
}
function shredWatch(shredOptions, postShredAction) {
var pattern = path.join(shredOptions.basePath, shredOptions.examplesDir, "**/*.*");
watch([pattern], function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
docShredder.shredSingleDir(shredOptions, event.path).then(function () {
postShredAction && postShredAction();
});
});
}
function jadeShredMapToJadeExampleMap(jadeShredMap, examplePaths) {
var exampleSet = {};
@ -199,67 +253,14 @@ function jadeShredMapToExampleJadeMap(jadeShredMap) {
function addKeyValue(map, key, value) {
var vals = map[key];
if (vals) {
if (vals.indexOf(value) == -1) {
vals.push(value);
}
} else {
map[key] = [value];
}
}
function buildShredMaps(shouldWrite) {
var options = _.extend(_shredOptions, {
jadeDir: '.',
outputDir: '.',
writeFilesEnabled: shouldWrite
});
return docShredder.buildShredMap(options).then(function(docs) {
return docs;
});
}
// returns a promise containing filePaths with any changed or added examples;
function getChangedExamples(sha) {
var examplesPath = path.join(_shredOptions.basePath, _shredOptions.examplesDir);
var relativePath = path.relative(process.cwd(), examplesPath);
return Git.Repository.open(".").then(function(repo) {
if (sha) {
return repo.getCommit(sha);
} else {
return repo.getHeadCommit();
}
}).then(function(commit) {
return commit.getDiff();
}).then(function(diffList) {
var filePaths = [];
diffList.forEach(function(diff) {
diff.patches().forEach(function(patch) {
if (patch.isAdded() || patch.isModified) {
var filePath = path.normalize(patch.newFile().path());
var isExample = filePath.indexOf(relativePath) >= 0;
// console.log(filePath + " isExample: " + isExample);
if (isExample) {
filePaths.push(filePath);
}
}
});
});
return filePaths;
}).catch(function(err) {
});
}
function shredWatch(shredOptions, postShredAction) {
var pattern = path.join(shredOptions.basePath, shredOptions.examplesDir, "**/*.*");
watch([pattern], function (event, done) {
console.log('Event type: ' + event.event); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
docShredder.shredSingleDir(shredOptions, event.path).then(function () {
postShredAction && postShredAction();
});
});
}
// added options are: shouldLog
// cb is function(err, stdout, stderr);

View File

@ -34,6 +34,7 @@
"karma-chrome-launcher": "^0.2.0",
"karma-jasmine": "^0.3.6",
"lodash": "^3.10.1",
"minimatch": "^2.0.10",
"nodegit": "^0.4.1",
"path": "^0.11.14",
"q": "^1.4.1",

View File

@ -3,12 +3,11 @@
mixin makeExample(path, fileName, title, stylePatterns)
- var language = attributes.language || getExtn(fileName);
- var format = attributes.format || "linenums";
- var extPath = getPathToFrags() + path + "/";
- var frag = getFrag(path, fileName);
if (title)
.example-title #{title}
code-example(language="#{language}" format="#{format}")
!= getFrag(extPath + fileName + ".md", stylePatterns)
!= styleString(frag, stylePatterns)
mixin makeTabs(path, fileNames, tabNames, stylePatterns)
- fileNames = fileNames.split(",");
@ -20,36 +19,55 @@ mixin makeTabs(path, fileNames, tabNames, stylePatterns)
- var fileName = fileNames[index].trim();
- var language = attributes.language || getExtn(fileName);
- var format = attributes.format || "linenums";
- var extPath = getPathToFrags() + path + "/";
- var frag = getFrag(path, fileName);
- var sps = Array.isArray(stylePatterns) ? stylePatterns[index] : stylePatterns;
code-pane(language="#{language}" name="#{tabName}" format="#{format}")
!= getFrag(extPath + fileName + ".md", sps)
!= styleString(frag, sps)
mixin makeJson(path, fileName, title, stylePatterns)
mixin makeJson(path, fileName, title, jsonConfig, stylePatterns)
- var language = attributes.language || getExtn(fileName);
- var format = attributes.format || "linenums";
- var extPath = getPathToFrags() + path + "/";
- var frag = getFrag(path, fileName);
- var json = unescapeHtml(frag);
- var jsonExtract = extractJson(json, jsonConfig);
if (title)
.example-title #{title}
code-example(language="#{language}" format="#{format}")
!= getFrag(extPath + fileName + ".md", stylePatterns)
!= styleString(jsonExtract, stylePatterns)
//---------------------------------------------------------------------------------------------------------
- var getFrag = function(fileName, stylePatterns) {
- var frag = partial(fileName);
- var getFrag = function(path, fileName) {
- var fullFileName = getPathToFrags() + path + "/" + fileName + '.md';
- var frag = partial(fullFileName);
- if (frag == null) {
- return "BAD FILENAME: " + fileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs();
- return "BAD FILENAME: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs();
- } else {
- // ``` gets translated to <pre><code>.....</code></pre> and we need
- // to remove this from the fragment prefix is 11 long and suffix is 13 long
- var r = frag.substring(11, frag.length-13);
- frag = frag.substring(11, frag.length-13);
- // Uncomment next line for debugging.
- // r = "FileName: " + fileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs() + "\n" + r;
- return styleString(r, stylePatterns);
- // frag = "FileName: " + fullFileName + " Current path: " + current.path + " PathToDocs: " + getPathToDocs() + "\n" + frag;
- return frag;
- }
- }
- var extractJson = function(json, jsonConfig ) {
- if (jsonConfig) {
- return extractJsonFragment(json, jsonConfig.rootPath || null, jsonConfig.paths || [], jsonConfig.space || " ");
- } else {
- return json;
- }
- }
- var unescapeHtml = function(s) {
- // can't break across multiple lines because of jade limitations.
- return s.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#039/g, "'");
- }
- var styleString = function(source, stylePatterns) {
- if (stylePatterns) {
- for (var styleName in stylePatterns) {
@ -115,7 +133,7 @@ mixin makeJson(path, fileName, title, stylePatterns)
//- properties according to the order in which they were inserted. ( the spec actually
//- discourages this assumption but this method will only
//- run on node (v8) and the assumption seems safe there. )
- function extractFragment(source, rootPath, extractPaths, space) {
- function extractJsonFragment(source, rootPath, extractPaths, space) {
- var objSource = JSON.parse(source);
- if (rootPath && rootPath.length > 0) {
- objSource = getSubObject(objSource, rootPath);
@ -124,7 +142,7 @@ mixin makeJson(path, fileName, title, stylePatterns)
- extractPaths.trim().split(",").forEach(function(dotPath) {
- processPath(objSource, objDest, dotPath );
- });
- var result = JSON.stringify(objDest, null, space);
- var result = JSON.stringify(objDest, null, space || " ");
- return result;
- function getSubObject(source, path) {

View File

@ -77,7 +77,7 @@ function createShredPackage(shredOptions) {
readFilesProcessor.basePath = options.basePath;
// Specify collections of source files that should contain the documentation to extract
var extns = ['*.js', '*.html', '*.ts', '*.css' ];
var extns = ['*.js', '*.html', '*.ts', '*.css', '*.json' ];
var includeFiles = extns.map(function(extn) {
if (options.includeSubdirs) {
return path.join(options.examplesDir, '**', extn);
@ -88,7 +88,7 @@ function createShredPackage(shredOptions) {
readFilesProcessor.sourceFiles = [ {
// Process all candidate files in `src` and its subfolders ...
include: includeFiles,
exclude: ['**/node_modules/**'],
exclude: ['**/node_modules/**', '**/typings/**'],
// When calculating the relative path to these files use this as the base path.
// So `src/foo/bar.js` will have relative path of `foo/bar.js`
basePath: options.examplesDir

View File

@ -19,11 +19,17 @@ module.exports = function fileShredder(log, regionExtractor) {
case 'css':
commentMarkers = ['/*'];
break;
case 'json':
break;
default:
return [];
}
log.info("fileShredder processing: " + fileInfo.projectRelativePath);
if (commentMarkers) {
return regionExtractor(fileInfo.content, commentMarkers);
} else {
return [ { content: fileInfo.content } ];
}
}
}
}

View File

@ -0,0 +1,15 @@
{
"name": "ng2-getting-started",
"version": "0.0.1",
"dependencies": {
"angular2": "2.0.0-alpha.35",
"es6-module-loader": "^0.16",
"systemjs": "^0.16",
"traceur": "0.0.91"
},
"scripts": {
"postinstall": "cd src && tsd reinstall -r -o && cd ..",
"tsc": "tsc -p src -w",
"start": "live-server --open=src"
}
}

View File

@ -0,0 +1,18 @@
```
{
"name": "ng2-getting-started",
"version": "0.0.1",
"dependencies": {
"angular2": "2.0.0-alpha.35",
"es6-module-loader": "^0.16",
"systemjs": "^0.16",
"traceur": "0.0.91"
},
"scripts": {
"postinstall": "cd src && tsd reinstall -r -o && cd ..",
"tsc": "tsc -p src -w",
"start": "live-server --open=src"
}
}
```

View File

@ -0,0 +1,11 @@
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
```

View File

@ -0,0 +1,27 @@
```
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"angular2/angular2.d.ts": {
"commit": "cd2e71bb1f0459197e733be66fdeafaec600514d"
},
"es6-promise/es6-promise.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"jasmine/jasmine.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx-lite.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
}
}
}
```

View File

@ -0,0 +1,8 @@
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs"
}
}
```

View File

@ -0,0 +1,23 @@
```
{
"name": "ng2-quickstart",
"version": "0.0.1",
"license": "ICS",
"repository": {},
"dependencies": {
"angular2": "2.0.0-alpha.35",
"es6-module-loader": "^0.16",
"systemjs": "^0.16",
"traceur": "0.0.91"
},
"devDependencies": {
"jasmine-core": "^2.3.4",
"zone.js": "^0.5.3"
},
"scripts": {
"postinstall": "cd src && tsd reinstall -r -o && cd ..",
"tsc": "tsc -p src -w",
"start": "live-server"
}
}
```

View File

@ -0,0 +1,11 @@
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
```

View File

@ -0,0 +1,27 @@
```
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"angular2/angular2.d.ts": {
"commit": "cd2e71bb1f0459197e733be66fdeafaec600514d"
},
"es6-promise/es6-promise.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"jasmine/jasmine.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx-lite.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
}
}
}
```

View File

@ -0,0 +1,17 @@
```
{
"name": "ng2-getting-started",
"version": "0.0.1",
"dependencies": {
"angular2": "2.0.0-alpha.35",
"es6-module-loader": "^0.16",
"systemjs": "^0.16",
"traceur": "0.0.91"
},
"scripts": {
"postinstall": "cd src && tsd reinstall -r -o && cd ..",
"tsc": "tsc -p src -w",
"start": "live-server --open=src"
}
}
```

View File

@ -0,0 +1,11 @@
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
```

View File

@ -0,0 +1,27 @@
```
{
"version": "v4",
"repo": "borisyankov/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"angular2/angular2.d.ts": {
"commit": "cd2e71bb1f0459197e733be66fdeafaec600514d"
},
"es6-promise/es6-promise.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"jasmine/jasmine.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
},
"rx/rx-lite.d.ts": {
"commit": "71d072b7354936b88d57c2029042d2da7c6ec0e7"
}
}
}
```

View File

@ -46,7 +46,7 @@ include ../../../_includes/_util-fns
#### Example:
code-example(format="linenums" language="html").
code-example(format="linenums" language="js").
+makeExample('styleguide', 'js/index.html', 'index.html')
:markdown
@ -68,7 +68,7 @@ include ../../../_includes/_util-fns
#### Example:
code-example(format="linenums" language="html").
code-example(format="linenums" language="js").
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test')
:markdown
@ -157,7 +157,7 @@ include ../../../_includes/_util-fns
name of the region. So a a file `foo.js` with a "test" region would have an extended file name of `foo-test.js`.
#### Example
code-example(format="linenums" language="html").
code-example(format="linenums" language="js").
+makeExample('styleguide', 'js/app-class-w-annotations.js')
:markdown
@ -198,7 +198,7 @@ include ../../../_includes/_util-fns
:markdown
A more complicated example might be:
code-example(format="linenums" language="html").
code-example(format="linenums" language="js").
- var stylePattern = { pnk: /script (src=.*&ampquot)/g, otl: /(my-app)/ };
+makeExample('styleguide', 'js/index.html', 'index.html', stylePattern )
@ -213,13 +213,50 @@ include ../../../_includes/_util-fns
pass in an array of stylePattern objects where each is paired with its corresponding 'tab'. If only a single stylePattern
object is passed in then it is assumed to apply to all of the tabs.
code-example(format="linenums" language="html").
code-example(format="linenums" language="js").
-var stylePatterns = [{ pnk: /script (src=.*&quot)/g }, {pnk: /(result)/ }];
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test', stylePatterns)
-var stylePatterns = [{ pnk: /script (src=.*&quot)/g }, {pnk: /(result)/ }];
+makeTabs('styleguide', 'js/index.html, js/spec.js', 'index.html,unit test', stylePatterns)
.l-sub-section
:markdown
### Including a JSON file or just parts of one
To include an '.json' file from somewhere in the `doc\_examples` folder you can use the `makeJson` mixin. The `makeExample`
and `makeTabs` mixins cannot be used for this purpose because there is no standard 'comment' marker in a json file.
The `makeJson` mixin does however provide a similar capability to selectively pick which portions of the '.json' file
to display.
The syntax for the `makeExample` mixin is:
#### +makeExample(basePath, filePath, title, jsonConfig, stylePattern)
- *basePath:* base path under '_examples'
- *filePath:* will be combined with the base path to locate the actual file
- *title:* (optional) title displayed above the included text.
- *jsonConfig:* (optional) an object that defines which portions of the .json file to select for display.
- *rootPath:* (optional default=null) a json property path at which the 'paths' parameter below should start.
- *paths:* a comma delimited list of property paths for those elements to be selected.
- *space:* (optional default=" " [2 spaces]) a String or Number object that's used to insert white space into the output JSON
- *stylePattern:* (*optional) allows additional styling via regular expression ( described above).
#### Example:
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "Entire package.json file")
+makeJson('styleguide', 'package.json', "Entire package.json file")
:markdown
A subset of the '.json' file can also be selected.
code-example(format="linenums" language="js").
+makeJson('styleguide', 'package.json', "Selected parts of the package.json file", {paths: 'version, scripts.tsc, scripts.start '} )
+makeJson('styleguide', 'package.json', "Selected parts of the package.json file", {paths: 'version, scripts.tsc, scripts.start '} )
.l-sub-section
:markdown
### Inline code and code examples provided directly i.e. not from an example file.