import colors from 'colors' ; import * as path from 'path' ; import yaml = require ( 'js-yaml' ) ; import { ApiModel } from '@microsoft/api-extractor-model' ; import { Text , FileSystem } from '@rushstack/node-core-library' ; import { IYamlTocItem } from '../yaml/IYamlTocFile' ; import { IYamlItem } from '../yaml/IYamlApiFile' ; import { YamlDocumenter } from './YamlDocumenter' ; interface ISnippetsFile { /**
     * The keys are API names like "Excel.Range.clear".
     * The values are TypeScript source code excerpts.
     */ [ apiName ] : string [ ] ; } /**
 * Extends YamlDocumenter with some custom logic that is specific to Office Add-ins.
 */ export class OfficeYamlDocumenter extends YamlDocumenter { private _snippets : ISnippetsFile ; private _snippetsAll : ISnippetsFile ; private _apiSetUrlDefault : string = '/office/dev/add-ins/reference/javascript-api-for-office' ; private _apiSetUrls : Record < string , string > = { Excel : '/office/dev/add-ins/reference/requirement-sets/excel-api-requirement-sets' , OneNote : '/office/dev/add-ins/reference/requirement-sets/onenote-api-requirement-sets' , Visio : '/office/dev/add-ins/reference/overview/visio-javascript-reference-overview' , Outlook : '/office/dev/add-ins/reference/requirement-sets/outlook-api-requirement-sets' , Word : '/office/dev/add-ins/reference/requirement-sets/word-api-requirement-sets' } ; public constructor ( apiModel , inputFolder , newDocfxNamespaces ? ) { super ( apiModel , newDocfxNamespaces ) ; const snippetsFilePath = path . join ( inputFolder , 'snippets.yaml' ) ; console . log ( 'Loading snippets from ' + snippetsFilePath ) ; const snippetsContent = FileSystem . readFile ( snippetsFilePath ) ; this . _snippets = yaml . load ( snippetsContent , { filename : snippetsFilePath } ) ; this . _snippetsAll = yaml . load ( snippetsContent , { filename : snippetsFilePath } ) ; } @override  public generateFiles ( outputFolder ) { super . generateFiles ( outputFolder ) ; console . log ( ) ; for ( const apiName of Object . keys ( this . _snippets ) ) { console . error ( colors . yellow ( 'Warning: Unused snippet ' + apiName ) ) ; } } @override  protected onGetTocRoot ( ) { return { name : 'API reference' , href : '~/docs-ref-autogen/overview/office.md' , items : [ ] } ; } @override  protected onCustomizeYamlItem ( yamlItem ) { const nameWithoutPackage = yamlItem . uid . replace ( /^[^.]+\!/ , '' ) ; if ( yamlItem . summary ) { yamlItem . summary = this . _fixupApiSet ( yamlItem . summary , yamlItem . uid ) ; yamlItem . summary = this . _fixBoldAndItalics ( yamlItem . summary ) ; } if ( yamlItem . remarks ) { yamlItem . remarks = this . _fixupApiSet ( yamlItem . remarks , yamlItem . uid ) ; yamlItem . remarks = this . _fixBoldAndItalics ( yamlItem . remarks ) ; } if ( yamlItem . syntax && yamlItem . syntax . parameters ) { yamlItem . syntax . parameters . forEach ( ( part ) => { if ( part . description ) { part . description = this . _fixBoldAndItalics ( part . description ) ; } } ) ; } const snippets = this . _snippetsAll [ nameWithoutPackage ] ; if ( snippets ) { delete this . _snippets [ nameWithoutPackage ] ; const snippetText = this . _generateExampleSnippetText ( snippets ) ; if ( yamlItem . remarks ) { yamlItem . remarks += snippetText ; } else if ( yamlItem . syntax && yamlItem . syntax . return ) { if ( ! yamlItem . syntax . return . description ) { yamlItem . syntax . return . description = '' ; } yamlItem . syntax . return . description += snippetText ; } else { yamlItem . remarks = snippetText ; } } } private _fixupApiSet ( markup , uid ) { markup = markup . replace ( /Api/ , 'API' ) ; return markup . replace ( /\\\[(API set:[^\]]+)\\\]/ , '\\[ [$1](' + this . _getApiSetUrl ( uid ) + ') \\]' ) ; } private _getApiSetUrl ( uid ) { for ( const key of Object . keys ( this . _apiSetUrls ) ) { const regexp = new RegExp ( key , 'i' ) ; if ( regexp . test ( uid ) ) { return this . _apiSetUrls [ key ] ; } } return this . _apiSetUrlDefault ; } private _fixBoldAndItalics ( text ) { return Text . replaceAll ( text , '\\*' , '*' ) ; } private _generateExampleSnippetText ( snippets ) { const text = [ '\n\n#### Examples\n' ] ; for ( const snippet of snippets ) { if ( snippet . search ( /await/ ) === - 1 ) { text . push ( '```javascript' ) ; } else { text . push ( '```typescript' ) ; } text . push ( snippet ) ; text . push ( '```' ) ; } return text . join ( '\n' ) ; } }