diff options
Diffstat (limited to 'docs/config/processors')
| -rw-r--r-- | docs/config/processors/index-page.js | 42 | ||||
| -rw-r--r-- | docs/config/processors/keywords.js | 91 | ||||
| -rw-r--r-- | docs/config/processors/pages-data.js | 200 | ||||
| -rw-r--r-- | docs/config/processors/versions-data.js | 42 | 
4 files changed, 375 insertions, 0 deletions
| diff --git a/docs/config/processors/index-page.js b/docs/config/processors/index-page.js new file mode 100644 index 00000000..3ba1ac73 --- /dev/null +++ b/docs/config/processors/index-page.js @@ -0,0 +1,42 @@ +var _ = require('lodash'); +var log = require('winston'); +var path = require('canonical-path'); +var deployment; + +module.exports = { +  name: 'index-page', +  runAfter: ['adding-extra-docs'], +  runBefore: ['extra-docs-added'], +  description: 'This processor creates docs that will be rendered as the index page for the app', +  init: function(config) { +    deployment = config.deployment; +    if ( !deployment || !deployment.environments ) { +      throw new Errro('No deployment environments found in the config.'); +    } +  }, +  process: function(docs) { + +    // Collect up all the areas in the docs +    var areas = {}; +    _.forEach(docs, function(doc) { +      if ( doc.area ) { +        areas[doc.area] = doc.area; +      } +    }); +    areas = _.keys(areas); + +    _.forEach(deployment.environments, function(environment) { + +      var indexDoc = _.defaults({ +        docType: 'indexPage', +        areas: areas +      }, environment); + +      indexDoc.id = 'index' + (environment.name === 'default' ? '' : '-' + environment.name); +      // Use .. to put it at the root of the build +      indexDoc.outputPath = indexDoc.id + '.html'; + +      docs.push(indexDoc); +    }); +  } +};
\ No newline at end of file diff --git a/docs/config/processors/keywords.js b/docs/config/processors/keywords.js new file mode 100644 index 00000000..6f7e9c21 --- /dev/null +++ b/docs/config/processors/keywords.js @@ -0,0 +1,91 @@ +var _ = require('lodash'); +var log = require('winston'); +var fs = require('fs'); +var path = require('canonical-path'); + +// Keywords to ignore +var wordsToIgnore = []; +var propertiesToIgnore; +var areasToSearch; + +// Keywords start with "ng:" or one of $, _ or a letter +var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/; + +module.exports = { +  name: 'keywords', +  runAfter: ['docs-processed'], +  runBefore: ['adding-extra-docs'], +  description: 'This processor extracts all the keywords from the document', +  init: function(config) { + +    // Load up the keywords to ignore, if specified in the config +    if ( config.processing.search && config.processing.search.ignoreWordsFile ) { + +      var ignoreWordsPath = path.resolve(config.basePath, config.processing.search.ignoreWordsFile); +      wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm); + +      log.debug('Loaded ignore words from "' + ignoreWordsPath + '"'); +      log.silly(wordsToIgnore); + +    } + +    areasToSearch = _.indexBy(config.get('processing.search.areasToSearch', ['api', 'guide', 'misc', 'error', 'tutorial'])); + +    propertiesToIgnore = _.indexBy(config.get('processing.search.propertiesToIgnore', [])); +    log.debug('Properties to ignore', propertiesToIgnore); + +  }, +  process: function(docs) { + +    var ignoreWordsMap = _.indexBy(wordsToIgnore); + +    // If the title contains a name starting with ng, e.g. "ngController", then add the module name +    // without the ng to the title text, e.g. "controller". +    function extractTitleWords(title) { +      var match = /ng([A-Z]\w*)/.exec(title); +      if ( match ) { +        title = title + ' ' + match[1].toLowerCase(); +      } +      return title; +    } + +    function extractWords(text, words, keywordMap) { + +      var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg); +      _.forEach(tokens, function(token){ +        var match = token.match(KEYWORD_REGEX); +        if (match){ +          key = match[1]; +          if ( !keywordMap[key]) { +            keywordMap[key] = true; +            words.push(key); +          } +        } +      }); +    } + + +    // We are only interested in docs that live in the right area +    docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; }); + +    _.forEach(docs, function(doc) { + +      var words = []; +      var keywordMap = _.clone(ignoreWordsMap); + +      // Search each top level property of the document for search terms +      _.forEach(doc, function(value, key) { +        if ( _.isString(value) && !propertiesToIgnore[key] ) { +          extractWords(value, words, keywordMap); +        } +      }); + +      doc.searchTerms = { +        titleWords: extractTitleWords(doc.name), +        keywords: _.sortBy(words).join(' ') +      }; + +    }); + +  } +};
\ No newline at end of file diff --git a/docs/config/processors/pages-data.js b/docs/config/processors/pages-data.js new file mode 100644 index 00000000..47896db5 --- /dev/null +++ b/docs/config/processors/pages-data.js @@ -0,0 +1,200 @@ +var _ = require('lodash'); +var path = require('canonical-path'); +var log = require('winston'); + +var AREA_NAMES = { +  api: 'API', +  guide: 'Developer Guide', +  misc: 'Miscellaneous', +  tutorial: 'Tutorial', +  error: 'Error Reference' +}; + +function getNavGroup(navGroupPages, groupName, pageSorter, pageMapper) { +   +  var navItems = _(navGroupPages) +    .sortBy(pageSorter) +    .map(pageMapper) +    .value(); + +  return { +    name: groupName, +    type: 'group', +    navItems: navItems +  }; +} + + +var navGroupMappers = { +  api: function(areaPages, areaName) { +    var navGroups = _(areaPages) +      .filter('module') // We are not interested in docs that are not in a module + +      .groupBy('module') + +      .map(function(modulePages, moduleName) { +        console.log('moduleName', moduleName); +        var navItems = []; +        var modulePage; + +        _(modulePages) + +          .groupBy('docType') + +          .tap(function(docTypes) { +            console.log(_.keys(docTypes)); +            // Extract the module page from the collection +            modulePage = docTypes.module[0]; +            delete docTypes.module; +          }) + +          .forEach(function(sectionPages, sectionName) { + +            if ( sectionPages.length > 0 ) { +              // Push a navItem for this section +              navItems.push({ +                name: sectionName, +                type: 'section', +                href: path.dirname(sectionPages[0].path) +              }); + +              // Push the rest of the sectionPages for this section +              _.forEach(sectionPages, function(sectionPage) { + +                navItems.push({ +                  name: sectionPage.name, +                  href: sectionPage.path, +                  type: sectionPage.docType +                }); + +              }); +            } +          }); +        return { +          name: moduleName, +          href: modulePage.path, +          type: 'group', +          navItems: navItems +        }; +      }) +      .value(); +    return navGroups; +  }, +  tutorial: function(pages, areaName) { +    return [getNavGroup(pages, areaName, 'step', function(page) { +      return { +        name: page.name, +        step: page.step, +        href: page.path, +        type: 'tutorial' +      }; +    })]; +  }, +  error: function(pages, areaName) { +    return [getNavGroup(pages, areaName, 'path', function(page) { +      return { +        name: page.name, +        href: page.path, +        type: 'error' +      }; +    })]; +  }, +  pages: function(pages, areaName) { +    return [getNavGroup(pages, areaName, 'path', function(page) { +      return { +        name: page.name, +        href: page.path, +        type: 'page' +      }; +    })]; +  } +}; + +var outputFolder; + +module.exports = { +  name: 'pages-data', +  description: 'This plugin will create a new doc that will be rendered as an angularjs module ' + +               'which will contain meta information about the pages and navigation', +  runAfter: ['adding-extra-docs', 'component-groups-generate'], +  runBefore: ['extra-docs-added'], +  init: function(config) { +    outputFolder = config.rendering.outputFolder; +  }, +  process: function(docs) { + +    _(docs) +    .filter(function(doc) { return doc.area === 'api'; }) +    .filter(function(doc) { return doc.docType === 'module'; }) +    .map(function(doc) { return _.pick(doc, ['id', 'module', 'docType', 'area']); }) +    .tap(function(docs) { +      console.log(docs); +    }); + + +    // We are only interested in docs that are in a area and not landing pages +    var navPages = _.filter(docs, function(page) { +      return page.area && page.docType != 'landingPage'; +    }); + +    // Generate an object collection of pages that is grouped by area e.g. +    // - area "api" +    //  - group "ng" +    //    - section "directive" +    //    - ngApp +    //    - ngBind +    //    - section "global" +    //    - angular.element +    //    - angular.bootstrap +    //    - section "service" +    //    - $compile +    //  - group "ngRoute" +    //    - section "directive" +    //    - ngView +    //    - section "service" +    //    - $route +    //     +    var areas = {}; +    _(navPages) +      .groupBy('area') +      .forEach(function(pages, areaName) { +        var navGroupMapper = navGroupMappers[areaName] || navGroupMappers['pages']; +        var areaTitle = AREA_NAMES[areaName]; + +        areas[areaName] = { +          id: areaName, +          name: areaTitle, +          navGroups: navGroupMapper(pages, areaTitle) +        }; +      }); + +    _.forEach(docs, function(doc) { +      if ( !doc.path ) { +        log.warn('Missing path property for ', doc.id); +      } +    }); + +    // Extract a list of basic page information for mapping paths to paritals and for client side searching +    var pages = _(docs) +      .map(function(doc) { +        var page = _.pick(doc, [ +          'docType', 'id', 'name', 'area', 'outputPath', 'path', 'searchTerms' +        ]); +        return page; +      }) +      .indexBy('path') +      .value(); + + +    var docData = { +      docType: 'pages-data', +      id: 'pages-data', +      template: 'pages-data.template.js', +      outputPath: 'js/pages-data.js', + +      areas: areas, +      pages: pages +    }; +    docs.push(docData); +  } +}; diff --git a/docs/config/processors/versions-data.js b/docs/config/processors/versions-data.js new file mode 100644 index 00000000..eb158e79 --- /dev/null +++ b/docs/config/processors/versions-data.js @@ -0,0 +1,42 @@ +var _ = require('lodash'); + +var version; +var versions; + +module.exports = { +  name: 'versions-data', +  description: 'This plugin will create a new doc that will be rendered as an angularjs module ' + +               'which will contain meta information about the versions of angular', +  runAfter: ['adding-extra-docs', 'pages-data'], +  runBefore: ['extra-docs-added'], +  init: function(config) { +    version = config.source.currentVersion; +    versions = config.source.previousVersions; + +    if ( !version ) { +      throw new Error('Invalid configuration.  Please provide a valid `source.currentVersion` property'); +    } +    if ( !versions ) { +      throw new Error('Invalid configuration.  Please provide a valid `source.previousVersions` property'); +    } +  }, +  process: function(docs) { + +    var versionDoc = { +      docType: 'versions-data', +      id: 'versions-data', +      template: 'versions-data.template.js', +      outputPath: 'js/versions-data.js', +    }; + +    versionDoc.currentVersion = version; + +    versionDoc.versions = _(versions) +      .filter(function(version) { return version.major > 0; }) +      .push(version) +      .reverse() +      .value(); + +    docs.push(versionDoc); +  } +};
\ No newline at end of file | 
