aboutsummaryrefslogtreecommitdiffstats
path: root/docs/config/processors/keywords.js
blob: 6f7e9c21288029c0c58f924ac22016da5861402f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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(' ')
      };

    });

  }
};