Просмотр исходного кода

Modify syntax for Crowi compatible template feature

Yuki Takei 7 лет назад
Родитель
Сommit
89583ffe91

+ 13 - 0
CHANGES.md

@@ -4,6 +4,19 @@ CHANGES
 ## 3.1.2-RC
 
 * Improvement: Add 'future' theme
+* Improvement: Modify syntax for Crowi compatible template feature
+    * *before*
+        ~~~
+        ``` template:/page/name
+        page contents
+        ```
+        ~~~
+    * *after*
+        ~~~
+        ::: template:/page/name
+        page contents
+        :::
+        ~~~
 * Fix: Posting to Slack doesn't work
     * Introduced by 3.1.0
 * Support: Upgrade libs

+ 2 - 11
resource/js/util/GrowiRenderer.js

@@ -3,8 +3,7 @@ import MarkdownIt from 'markdown-it';
 import Linker        from './PreProcessor/Linker';
 import CsvToTable    from './PreProcessor/CsvToTable';
 import XssFilter     from './PreProcessor/XssFilter';
-
-import Template from './LangProcessor/Template';
+import CrowiTemplate from './PostProcessor/CrowiTemplate';
 
 import CommonPluginsConfigurer from './markdown-it/common-plugins';
 import EmojiConfigurer from './markdown-it/emoji';
@@ -38,12 +37,9 @@ export default class GrowiRenderer {
       new XssFilter(crowi),
     ];
     this.postProcessors = this.originRenderer.postProcessors || [
+      new CrowiTemplate(crowi),
     ];
 
-    this.langProcessors = this.originRenderer.langProcessors || {
-      'template': new Template(crowi),
-    };
-
     this.initMarkdownItConfigurers = this.initMarkdownItConfigurers.bind(this);
     this.setup = this.setup.bind(this);
     this.process = this.process.bind(this);
@@ -147,11 +143,6 @@ export default class GrowiRenderer {
       const lang = langAndFn[0];
       const langFn = langAndFn[1] || null;
 
-      // process langProcessors
-      if (this.langProcessors[lang] != null) {
-        return this.langProcessors[lang].process(code, langExt);
-      }
-
       const citeTag = (langFn) ? `<cite>${langFn}</cite>` : '';
       if (hljs.getLanguage(lang)) {
         try {

+ 0 - 72
resource/js/util/LangProcessor/Template.js

@@ -1,72 +0,0 @@
-import dateFnsFormat from 'date-fns/format';
-
-export default class Template {
-
-  constructor(crowi) {
-    this.templatePattern = {
-      'year': this.getYear,
-      'month': this.getMonth,
-      'date': this.getDate,
-      'user': this.getUser,
-    };
-  }
-
-  getYear() {
-    return dateFnsFormat(new Date(), 'YYYY');
-  }
-
-  getMonth() {
-    return dateFnsFormat(new Date(), 'YYYY/MM');
-  }
-
-  getDate() {
-    return dateFnsFormat(new Date(), 'YYYY/MM/DD');
-  }
-
-  getUser() {
-    // FIXME
-    const username = window.crowi.me || null;
-
-    if (!username) {
-      return '';
-    }
-
-    return `/user/${username}`;
-  }
-
-  parseTemplateString(templateString) {
-    let parsed = templateString;
-
-    Object.keys(this.templatePattern).forEach(key => {
-      const k = key .replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-      const matcher = new RegExp(`{${k}}`, 'g');
-      if (parsed.match(matcher)) {
-        const replacer = this.templatePattern[key]();
-        parsed = parsed.replace(matcher, replacer);
-      }
-    });
-
-    return parsed;
-  }
-
-  process(code, lang) {
-    const templateId = new Date().getTime().toString(16) + Math.floor(1000 * Math.random()).toString(16);
-    let pageName = lang;
-    if (lang.match(':')) {
-      pageName = this.parseTemplateString(lang.split(':')[1]);
-    }
-    code = this.parseTemplateString(code);
-
-    const content = `
-      <div class="page-template-builder">
-        <button class="template-create-button btn btn-default" data-template="${templateId}" data-path="${pageName}">
-          <i class="fa fa-pencil"></i> ${pageName}
-        </button>
-        <pre><code id="${templateId}" class="lang-${lang}">${code}\n</code></pre>
-      </div>`;
-
-    // wrap with <pre-dummy>
-    //   to avoid to be wrapped with <pre><code> by markdown-it
-    return `<pre-dummy>${content}<pre-dummy>\n`;
-  }
-}

+ 82 - 0
resource/js/util/PostProcessor/CrowiTemplate.js

@@ -0,0 +1,82 @@
+import dateFnsFormat from 'date-fns/format';
+
+export default class CrowiTemplate {
+
+  constructor(crowi) {
+    this.templatePattern = {
+      'year': this.getYear,
+      'month': this.getMonth,
+      'date': this.getDate,
+      'user': this.getUser,
+    };
+  }
+
+  process(markdown) {
+    // see: https://regex101.com/r/WR6IvX/3
+    return markdown.replace(/:::\s*(\S+)[\r\n]((.|[\r\n])*?)[\r\n]:::/gm, (all, group1, group2) => {
+      const lang = group1;
+      let code = group2;
+
+      if (!lang.match(/^template/)) {
+        return all;
+      }
+
+      const templateId = new Date().getTime().toString(16) + Math.floor(1000 * Math.random()).toString(16);
+      let pageName = lang;
+      if (lang.match(':')) {
+        pageName = this.parseTemplateString(lang.split(':')[1]);
+      }
+      code = this.parseTemplateString(code);
+
+      return (
+        /* eslint-disable quotes */
+        `<div class="page-template-builder">` +
+          `<button class="template-create-button btn btn-default" data-template="${templateId}" data-path="${pageName}">` +
+            `<i class="fa fa-pencil"></i> ${pageName}` +
+          `</button>` +
+          `<pre><code id="${templateId}" class="lang-${lang}">${code}\n</code></pre>` +
+        `</div>`
+        /* eslint-enable */
+      );
+    });
+  }
+
+  getYear() {
+    return dateFnsFormat(new Date(), 'YYYY');
+  }
+
+  getMonth() {
+    return dateFnsFormat(new Date(), 'YYYY/MM');
+  }
+
+  getDate() {
+    return dateFnsFormat(new Date(), 'YYYY/MM/DD');
+  }
+
+  getUser() {
+    // FIXME
+    const username = window.crowi.me || null;
+
+    if (!username) {
+      return '';
+    }
+
+    return `/user/${username}`;
+  }
+
+  parseTemplateString(templateString) {
+    let parsed = templateString;
+
+    Object.keys(this.templatePattern).forEach(key => {
+      const k = key .replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+      const matcher = new RegExp(`{${k}}`, 'g');
+      if (parsed.match(matcher)) {
+        const replacer = this.templatePattern[key]();
+        parsed = parsed.replace(matcher, replacer);
+      }
+    });
+
+    return parsed;
+  }
+
+}