Blame view

node_modules/markdown-it/lib/rules_core/replacements.js 2.73 KB
290144e9   易尊强   第一次
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  // Simple typographyc replacements
  //
  // (c) (C) → ©
  // (tm) (TM) → ™
  // (r) (R) → ®
  // +- → ±
  // (p) (P) -> §
  // ... → … (also ?.... → ?.., !.... → !..)
  // ???????? → ???, !!!!! → !!!, `,,` → `,`
  // -- → –, --- → —
  //
  'use strict';
  
  // TODO:
  // - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾
  // - miltiplication 2 x 4 -> 2 × 4
  
  var RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/;
  
  // Workaround for phantomjs - need regex without /g flag,
  // or root check will fail every second time
  var SCOPED_ABBR_TEST_RE = /\((c|tm|r|p)\)/i;
  
  var SCOPED_ABBR_RE = /\((c|tm|r|p)\)/ig;
  var SCOPED_ABBR = {
    c: '©',
    r: '®',
    p: '§',
    tm: '™'
  };
  
  function replaceFn(match, name) {
    return SCOPED_ABBR[name.toLowerCase()];
  }
  
  function replace_scoped(inlineTokens) {
    var i, token, inside_autolink = 0;
  
    for (i = inlineTokens.length - 1; i >= 0; i--) {
      token = inlineTokens[i];
  
      if (token.type === 'text' && !inside_autolink) {
        token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn);
      }
  
      if (token.type === 'link_open' && token.info === 'auto') {
        inside_autolink--;
      }
  
      if (token.type === 'link_close' && token.info === 'auto') {
        inside_autolink++;
      }
    }
  }
  
  function replace_rare(inlineTokens) {
    var i, token, inside_autolink = 0;
  
    for (i = inlineTokens.length - 1; i >= 0; i--) {
      token = inlineTokens[i];
  
      if (token.type === 'text' && !inside_autolink) {
        if (RARE_RE.test(token.content)) {
          token.content = token.content
                      .replace(/\+-/g, '±')
                      // .., ..., ....... -> …
                      // but ?..... & !..... -> ?.. & !..
                      .replace(/\.{2,}/g, '…').replace(/([?!])…/g, '$1..')
                      .replace(/([?!]){4,}/g, '$1$1$1').replace(/,{2,}/g, ',')
                      // em-dash
                      .replace(/(^|[^-])---([^-]|$)/mg, '$1\u2014$2')
                      // en-dash
                      .replace(/(^|\s)--(\s|$)/mg, '$1\u2013$2')
                      .replace(/(^|[^-\s])--([^-\s]|$)/mg, '$1\u2013$2');
        }
      }
  
      if (token.type === 'link_open' && token.info === 'auto') {
        inside_autolink--;
      }
  
      if (token.type === 'link_close' && token.info === 'auto') {
        inside_autolink++;
      }
    }
  }
  
  
  module.exports = function replace(state) {
    var blkIdx;
  
    if (!state.md.options.typographer) { return; }
  
    for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {
  
      if (state.tokens[blkIdx].type !== 'inline') { continue; }
  
      if (SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)) {
        replace_scoped(state.tokens[blkIdx].children);
      }
  
      if (RARE_RE.test(state.tokens[blkIdx].content)) {
        replace_rare(state.tokens[blkIdx].children);
      }
  
    }
  };