| 
									
										
										
										
											2017-04-26 17:58:57 +01:00
										 |  |  | const { parseAttributes, renderAttributes } = require('../../helpers/utils'); | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Search the renderedContent looking for code examples that have a path (and optionally a region) attribute. | 
					
						
							|  |  |  |  * When they are found replace their content with the appropriate doc-region parsed previously from an example file. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-10-30 21:25:48 +00:00
										 |  |  | module.exports = function renderExamples(getExampleRegion, log, createDocMessage) { | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  |   return { | 
					
						
							|  |  |  |     $runAfter: ['docs-rendered'], | 
					
						
							|  |  |  |     $runBefore: ['writing-files'], | 
					
						
							| 
									
										
										
										
											2017-10-30 21:25:48 +00:00
										 |  |  |     ignoreBrokenExamples: false, | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  |     $process: function(docs) { | 
					
						
							| 
									
										
										
										
											2018-10-17 17:35:20 +03:00
										 |  |  |       const titleVsHeaderErrors = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  |       docs.forEach(doc => { | 
					
						
							|  |  |  |         if (doc.renderedContent) { | 
					
						
							|  |  |  |           // We match either `code-example` or `code-pane` elements that have a path attribute
 | 
					
						
							| 
									
										
										
										
											2017-10-23 17:58:49 +01:00
										 |  |  |           doc.renderedContent = doc.renderedContent.replace( | 
					
						
							|  |  |  |             /<(code-example|code-pane)([^>]*)>[^<]*<\/([^>]+)>/g, | 
					
						
							|  |  |  |             (original, openingTag, attributes, closingTag) => { | 
					
						
							|  |  |  |               const attrMap = parseAttributes(attributes); | 
					
						
							| 
									
										
										
										
											2018-10-17 17:35:20 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |               if (attrMap.hasOwnProperty('title')) { | 
					
						
							|  |  |  |                 titleVsHeaderErrors.push(createDocMessage( | 
					
						
							|  |  |  |                   `Using the "title" attribute for specifying a ${openingTag} header is no longer supported. ` + | 
					
						
							|  |  |  |                   `Use the "header" attribute instead.\n<${openingTag}${attributes}>`, doc)); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-23 17:58:49 +01:00
										 |  |  |               if (attrMap.path) { | 
					
						
							| 
									
										
										
										
											2017-10-30 21:25:48 +00:00
										 |  |  |                 try { | 
					
						
							|  |  |  |                   if (closingTag !== openingTag) { | 
					
						
							|  |  |  |                     // The markdown renderer will wrap what it thinks is a paragraph in `<p>` and `</p>` tags.
 | 
					
						
							|  |  |  |                     // If you do not leave a blank line between a paragraph of text and a `<code-example>` then
 | 
					
						
							|  |  |  |                     // the markdown renderer may add a paragraph marker "in-between" the opening and closing
 | 
					
						
							|  |  |  |                     // tags of the code-example. For example:
 | 
					
						
							|  |  |  |                     //
 | 
					
						
							|  |  |  |                     // ```
 | 
					
						
							|  |  |  |                     // Some paragraph
 | 
					
						
							|  |  |  |                     // <code-example path="...">
 | 
					
						
							|  |  |  |                     //
 | 
					
						
							|  |  |  |                     // </code-example>
 | 
					
						
							|  |  |  |                     // ```
 | 
					
						
							|  |  |  |                     //
 | 
					
						
							|  |  |  |                     // will be rendered as:
 | 
					
						
							|  |  |  |                     //
 | 
					
						
							|  |  |  |                     // ```
 | 
					
						
							|  |  |  |                     // <p>Some paragraph
 | 
					
						
							|  |  |  |                     // <code-example path="...">
 | 
					
						
							|  |  |  |                     // </p>
 | 
					
						
							|  |  |  |                     // </code-example>
 | 
					
						
							|  |  |  |                     // ```
 | 
					
						
							|  |  |  |                     throw new Error( | 
					
						
							|  |  |  |                       'Badly formed example: ' + original + ' - closing tag does not match opening tag.\n' + | 
					
						
							|  |  |  |                       ' - Perhaps you forgot to put a blank line before the example?'); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                   // We found a path attribute so look up the example and rebuild the HTML
 | 
					
						
							|  |  |  |                   const exampleContent = getExampleRegion(doc, attrMap.path, attrMap.region); | 
					
						
							|  |  |  |                   return `<${openingTag}${renderAttributes(attrMap)}>\n${exampleContent}\n</${openingTag}>`; | 
					
						
							|  |  |  |                 } catch(e) { | 
					
						
							|  |  |  |                   log.warn(createDocMessage(e.message, doc)); | 
					
						
							|  |  |  |                   if (!this.ignoreBrokenExamples) { | 
					
						
							|  |  |  |                     throw e; | 
					
						
							|  |  |  |                   } | 
					
						
							| 
									
										
										
										
											2017-10-23 17:58:49 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |               // No path attribute so just ignore this one
 | 
					
						
							|  |  |  |               return original; | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-10-17 17:35:20 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (titleVsHeaderErrors.length) { | 
					
						
							|  |  |  |         titleVsHeaderErrors.forEach(err => log.error(err)); | 
					
						
							|  |  |  |         throw new Error('Some code snippets use the `title` attribute instead of `header`.'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-03-25 21:07:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; |