| 
									
										
										
											
												feat(aio): support annotating JSON files with doc-regions
This change allows the example writer to add doc-region annotations to
files that do not allow comments. This is done by creating a clone of the
file and adding `.annotated` to the file name. This new file can contain
inline `// ...` comments that can be used to annotate the doc regions.
Example:
**package.json**
```
{
  "name": "angular.io",
  "version": "0.0.0",
  "main": "index.js",
  "repository": "git@github.com:angular/angular.git",
  "author": "Angular",
  "license": "MIT",
  "private": true,
}
````
**package.json.annotated**
```
{
  "name": "angular.io",
// #docregion version
  "version": "0.0.0",
// #enddocregion
  "main": "index.js",
  "repository": "git@github.com:angular/angular.git",
  "author": "Angular",
  "license": "MIT",
  "private": true,
}
````
This region can then be referenced in examples just like any other doc region:
```
{@example 'package.json' region="version"}
```
											
										 
											2017-02-21 13:09:57 +00:00
										 |  |  | const {extname} = require('canonical-path'); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:58:57 +01:00
										 |  |  | const {mapObject} = require('../../helpers/utils'); | 
					
						
							| 
									
										
										
										
											2017-01-26 14:03:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = function collectExamples(exampleMap, regionParser, log, createDocMessage) { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     $runAfter: ['files-read'], | 
					
						
							|  |  |  |     $runBefore: ['parsing-tags'], | 
					
						
							|  |  |  |     $validate: {exampleFolders: {presence: true}}, | 
					
						
							| 
									
										
										
										
											2017-09-19 10:15:39 +01:00
										 |  |  |     exampleFolders: [], | 
					
						
							|  |  |  |     ignoredExamples: {}, | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Call this method to indicate to the processor that some files, that actually exist, | 
					
						
							|  |  |  |      * have been filtered out from being processed. | 
					
						
							|  |  |  |      * @param paths an array of relative paths to the examples that have been ignored. | 
					
						
							|  |  |  |      * @param gitIgnorePath the path to the gitignore file that caused this example to be ignored. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     registerIgnoredExamples(paths, gitIgnorePath) { | 
					
						
							|  |  |  |       paths.forEach(path => { this.ignoredExamples[path] = gitIgnorePath; }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Call this method to find out if an example was ignored. | 
					
						
							|  |  |  |      * @param path a relative path to the example file to test for being ignored. | 
					
						
							|  |  |  |      * @returns the path to the .gitignore file. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     isExampleIgnored(path) { | 
					
						
							|  |  |  |       return this.ignoredExamples[path]; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     $process(docs) { | 
					
						
							| 
									
										
										
										
											2017-01-26 14:03:53 +00:00
										 |  |  |       const exampleFolders = this.exampleFolders; | 
					
						
							| 
									
										
										
										
											2018-02-28 20:10:14 +00:00
										 |  |  |       exampleFolders.forEach(folder => exampleMap[folder] = exampleMap[folder] || {}); | 
					
						
							| 
									
										
										
										
											2017-01-26 14:03:53 +00:00
										 |  |  |       const regionDocs = []; | 
					
						
							|  |  |  |       docs = docs.filter((doc) => { | 
					
						
							|  |  |  |         if (doc.docType === 'example-file') { | 
					
						
							|  |  |  |           try { | 
					
						
							|  |  |  |             // find the first matching folder
 | 
					
						
							|  |  |  |             exampleFolders.some((folder) => { | 
					
						
							|  |  |  |               if (doc.fileInfo.relativePath.indexOf(folder) === 0) { | 
					
						
							|  |  |  |                 const relativePath = | 
					
						
							|  |  |  |                     doc.fileInfo.relativePath.substr(folder.length).replace(/^\//, ''); | 
					
						
							|  |  |  |                 exampleMap[folder][relativePath] = doc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												feat(aio): support annotating JSON files with doc-regions
This change allows the example writer to add doc-region annotations to
files that do not allow comments. This is done by creating a clone of the
file and adding `.annotated` to the file name. This new file can contain
inline `// ...` comments that can be used to annotate the doc regions.
Example:
**package.json**
```
{
  "name": "angular.io",
  "version": "0.0.0",
  "main": "index.js",
  "repository": "git@github.com:angular/angular.git",
  "author": "Angular",
  "license": "MIT",
  "private": true,
}
````
**package.json.annotated**
```
{
  "name": "angular.io",
// #docregion version
  "version": "0.0.0",
// #enddocregion
  "main": "index.js",
  "repository": "git@github.com:angular/angular.git",
  "author": "Angular",
  "license": "MIT",
  "private": true,
}
````
This region can then be referenced in examples just like any other doc region:
```
{@example 'package.json' region="version"}
```
											
										 
											2017-02-21 13:09:57 +00:00
										 |  |  |                 // We treat files that end in `.annotated` specially
 | 
					
						
							|  |  |  |                 // They are used to annotate files that cannot contain comments, such as JSON
 | 
					
						
							|  |  |  |                 // So you provide two files: `xyz.json` and `xyz.json.annotated`, which is a copy
 | 
					
						
							|  |  |  |                 // of the original but contains inline doc region comments
 | 
					
						
							|  |  |  |                 let fileType = doc.fileInfo.extension; | 
					
						
							|  |  |  |                 if (fileType === 'annotated') { | 
					
						
							|  |  |  |                   fileType = extname(doc.fileInfo.baseName).substr(1) + '.' + fileType; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 const parsedRegions = regionParser(doc.content, fileType); | 
					
						
							| 
									
										
										
										
											2017-01-26 14:03:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 log.debug( | 
					
						
							|  |  |  |                     'found example file', folder, relativePath, Object.keys(parsedRegions.regions)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 doc.renderedContent = parsedRegions.contents; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Map each region into a doc that can be put through the rendering pipeline
 | 
					
						
							|  |  |  |                 doc.regions = mapObject(parsedRegions.regions, (regionName, regionContents) => { | 
					
						
							|  |  |  |                   const regionDoc = | 
					
						
							|  |  |  |                       createRegionDoc(folder, relativePath, regionName, regionContents); | 
					
						
							|  |  |  |                   regionDocs.push(regionDoc); | 
					
						
							|  |  |  |                   return regionDoc; | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           } catch (e) { | 
					
						
							|  |  |  |             throw new Error(createDocMessage(e.message, doc, e)); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return docs.concat(regionDocs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function createRegionDoc(folder, relativePath, regionName, regionContents) { | 
					
						
							|  |  |  |   const path = folder + '/' + relativePath; | 
					
						
							| 
									
										
										
										
											2017-04-01 21:34:10 +03:00
										 |  |  |   const id = path + '#' + regionName; | 
					
						
							| 
									
										
										
										
											2017-01-26 14:03:53 +00:00
										 |  |  |   return { | 
					
						
							|  |  |  |     docType: 'example-region', | 
					
						
							|  |  |  |     path: path, | 
					
						
							|  |  |  |     name: regionName, | 
					
						
							|  |  |  |     id: id, | 
					
						
							|  |  |  |     aliases: [id], | 
					
						
							|  |  |  |     contents: regionContents | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2017-04-01 21:34:10 +03:00
										 |  |  | } |