Sotaro KARASAWA 8 лет назад
Родитель
Сommit
41cd70c485

+ 4 - 0
lib/crowi/index.js

@@ -114,6 +114,10 @@ Crowi.prototype.getConfig = function() {
   return this.config;
 };
 
+Crowi.prototype.getEnv = function() {
+  return this.env;
+};
+
 Crowi.prototype.getAssetList = function() {
   if (this.node_env !== 'development') {
     return this.assets;

+ 4 - 0
lib/models/config.js

@@ -220,6 +220,7 @@ module.exports = function(crowi) {
   configSchema.statics.getLocalconfig = function(config)
   {
     const Config = this;
+    const env = crowi.getEnv();
 
     const local_config = {
       crowi: {
@@ -230,6 +231,9 @@ module.exports = function(crowi) {
         image: Config.isUploadable(config),
         file: Config.fileUploadEnabled(config),
       },
+      env: {
+        PLANTUML_URI: env.PLANTUML_URI || null,
+      },
     };
 
     return local_config;

+ 4 - 0
resource/css/_wiki.scss

@@ -124,6 +124,10 @@ div.body {
     border: solid 1px #ccc;
     max-width: 100%;
   }
+  .noborder img, .img.noborder {
+    box-shadow: none;
+    border: none;
+  }
 
   img.emoji {
     width: 0.95em;

+ 1 - 1
resource/js/app.js

@@ -37,7 +37,7 @@ window.crowi = crowi;
 crowi.setConfig(JSON.parse(document.getElementById('crowi-context-hydrate').textContent || '{}'));
 crowi.fetchUsers();
 
-const crowiRenderer = new CrowiRenderer();
+const crowiRenderer = new CrowiRenderer(crowi);
 window.crowiRenderer = crowiRenderer;
 
 const componentMappings = {

+ 11 - 8
resource/js/util/CrowiRenderer.js

@@ -9,25 +9,28 @@ import Emoji         from './PostProcessor/Emoji';
 
 import Tsv2Table from './LangProcessor/Tsv2Table';
 import Template from './LangProcessor/Template';
+import PlantUML from './LangProcessor/PlantUML';
 
 export default class CrowiRenderer {
 
 
-  constructor(plugins) {
+  constructor(crowi) {
+    this.crowi = crowi;
 
     this.preProcessors = [
-      new MarkdownFixer(),
-      new Linker(),
-      new ImageExpander(),
+      new MarkdownFixer(crowi),
+      new Linker(crowi),
+      new ImageExpander(crowi),
     ];
     this.postProcessors = [
-      new Emoji(),
+      new Emoji(crowi),
     ];
 
     this.langProcessors = {
-      'tsv': new Tsv2Table(),
-      'tsv-h': new Tsv2Table({header: true}),
-      'template': new Template(),
+      'tsv': new Tsv2Table(crowi),
+      'tsv-h': new Tsv2Table(crowi, {header: true}),
+      'template': new Template(crowi),
+      'plantuml': new PlantUML(crowi),
     };
 
     this.parseMarkdown = this.parseMarkdown.bind(this);

+ 42 - 0
resource/js/util/LangProcessor/PlantUML.js

@@ -0,0 +1,42 @@
+import plantuml from 'plantuml-encoder';
+import crypto from 'crypto';
+
+export default class PlantUML {
+
+  constructor(crowi) {
+    this.crowi = crowi;
+
+  }
+
+  generateId(token) {
+    const hasher = require('crypto').createHash('md5');
+    hasher.update(token);
+    return hasher.digest('hex');
+  }
+
+  process(code, lang) {
+    const config = crowi.getConfig();
+    if (!config.env.PLANTUML_URI) {
+      return `<pre class="wiki-code"><code>${Crowi.escape(code, true)}\n</code></pre>`;
+    }
+
+    let plantumlUri = config.env.PLANTUML_URI;
+    if (plantumlUri.substr(-1) !== '/') {
+      plantumlUri += '/';
+    }
+    const id = this.generateId(code + lang);
+    const encoded = plantuml.encode(`@startuml
+
+skinparam monochrome true
+
+${code}
+@enduml`);
+
+    return `
+      <div id="${id}" class="plantuml noborder">
+        <img src="${plantumlUri}svg/${encoded}">
+      </div>
+    `;
+  }
+}
+

+ 1 - 1
resource/js/util/LangProcessor/Template.js

@@ -2,7 +2,7 @@ import moment from 'moment';
 
 export default class Template {
 
-  constructor() {
+  constructor(crowi) {
     this.templatePattern = {
       'year': this.getYear,
       'month': this.getMonth,

+ 1 - 1
resource/js/util/LangProcessor/Tsv2Table.js

@@ -1,7 +1,7 @@
 
 export default class Tsv2Table {
 
-  constructor(option) {
+  constructor(crowi, option) {
     if (!option) {
       option = {};
     }