kstm-su / isctsc2021Summer

ictsc2021夏の陣チームkstm用
0 stars 0 forks source link

19. 何もしてないのに壊れた! #10

Closed kitakou0313 closed 3 years ago

kitakou0313 commented 3 years ago

概要

Markdownのコンテンツをブラウザで閲覧できる社内サイトがある。 UML図も埋め込みが可能であったが、数ヶ月前から図の部分だけが表示されなくなってしまった。 それも、ほぼ同時期に、複数の端末で。

サーバ側は長年変更しておらず、特に心当たりもない。一体なぜ……。

リンク

https://contest.ictsc.net/#/problems/4e9be1d8-133b-445b-9c62-3526b113233f

Cyndaquil1999 commented 3 years ago

webserverのtools/node_modules/markdown-it-plantumlにあるindex.jsの設定関連なのかなあ...?

実際に動いてる部分見たがuml図がuml diagramのままで上手く表示されていない感じなので設定がうまくいってなさそうに思う。

Cyndaquil1999 commented 3 years ago

index.js

// Process block-level uml diagrams
//
'use strict';

module.exports = function umlPlugin(md, options) {   

  function generateSourceDefault(umlCode, pluginOptions) {
    var imageFormat = pluginOptions.imageFormat || 'svg';
    var diagramName = pluginOptions.diagramName || 'uml';
    var server = pluginOptions.server || 'https://www.plantuml.com/plantuml';
    var deflate = require('./lib/deflate.js');       
    var zippedCode = deflate.encode64(
      deflate.zip_deflate(
        unescape(encodeURIComponent(
          '@start' + diagramName + '\n' + umlCode + '\n@end' + diagramName)),
        9
      )
    );

    return server + '/' + imageFormat + '/' + zippedCode;
  }

  options = options || {};

  var openMarker = options.openMarker || '@startuml',      openChar = openMarker.charCodeAt(0),
      closeMarker = options.closeMarker || '@enduml',      closeChar = closeMarker.charCodeAt(0),
      render = options.render || md.renderer.rules.image,
      generateSource = options.generateSource || generateSourceDefault;

  function uml(state, startLine, endLine, silent) {  
    var nextLine, markup, params, token, i,
        autoClosed = false,
        start = state.bMarks[startLine] + state.tShift[startLine],
        max = state.eMarks[startLine];

    // Check out the first character quickly,        
    // this should filter out most of non-uml blocks 
    //
    if (openChar !== state.src.charCodeAt(start)) { return false; }

    // Check out the rest of the marker string       
    //
    for (i = 0; i < openMarker.length; ++i) {        
      if (openMarker[i] !== state.src[start + i]) { return false; }
    }

    markup = state.src.slice(start, start + i);      
    params = state.src.slice(start + i, max);        

    // Since start is found, we can report success here in validation mode
    //
    if (silent) { return true; }

    // Search for the end of the block
    //
    nextLine = startLine;

    for (;;) {
      nextLine++;
      if (nextLine >= endLine) {
        // unclosed block should be autoclosed by end of document.
        // also block seems to be autoclosed by end of parent
        break;
      }

      start = state.bMarks[nextLine] + state.tShift[nextLine];
      max = state.eMarks[nextLine];

      if (start < max && state.sCount[nextLine] < state.blkIndent) {
        // non-empty line with negative indent should stop the list:
        // - ```
        //  test
        break;
      }

      if (closeChar !== state.src.charCodeAt(start)) 
{
        // didn't find the closing fence
        continue;
      }

      if (state.sCount[nextLine] > state.sCount[startLine]) {
        // closing fence should not be indented with 
respect of opening fence
        continue;
      }

      var closeMarkerMatched = true;
      for (i = 0; i < closeMarker.length; ++i) {     
        if (closeMarker[i] !== state.src[start + i]) 
{
          closeMarkerMatched = false;
          break;
        }
      }

      if (!closeMarkerMatched) {
        continue;
      }

      // make sure tail has spaces only
      if (state.skipSpaces(start + i) < max) {       
        continue;
      }

      // found!
      autoClosed = true;
      break;
    }

    var contents = state.src
      .split('\n')
      .slice(startLine + 1, nextLine)
      .join('\n');

    // We generate a token list for the alt property, to mimic what the image parser does.
    var altToken = [];
    // Remove leading space if any.
    var alt = params ? params.slice(1) : 'uml diagram';
    state.md.inline.parse(
      alt,
      state.md,
      state.env,
      altToken
    );

    token = state.push('uml_diagram', 'img', 0);
    // alt is constructed from children. No point in populating it here.
    token.attrs = [ [ 'src', generateSource(contents, options) ], [ 'alt', '' ] ];     
    token.block = true;
    token.children = altToken;
    token.info = params;
    token.map = [ startLine, nextLine ];
    token.markup = markup;

    state.line = nextLine + (autoClosed ? 1 : 0);

    return true;
  }

  md.block.ruler.before('fence', 'uml_diagram', uml, {
    alt: [ 'paragraph', 'reference', 'blockquote', 'list' ]
  });
  md.renderer.rules.uml_diagram = render;
};
Cyndaquil1999 commented 3 years ago

conv.js

const path = require('path')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const save_dir_page = '/var/www/html/'

const md = require('markdown-it')({
    html: true,
    breaks: true,
    linkify: true,
    langPrefix: ''
}).use(require('markdown-it-plantuml'), {
    openMarker: '```uml',
    closeMarker: '```',
    server: 'http://192.168.16.200:10080'   // plantuml-server
}).use(require('markdown-it-meta'), {
})

async function main(input) {
    try {
        let markdown = await readFile(input, 'utf-8');
        let html_body = md.render(markdown);

        let html_header = `<!DOCTYPE html>
<title>${md.meta.title}</title>
<link href="/assets/github-markdown.css" rel="stylesheet">
<link href="/assets/page.css" rel="stylesheet">
<div class="markdown-body">
<h1>${md.meta.title}</h1>
`

        await writeFile(save_dir_page + path.basename(input, '.md') + '.html', html_header + html_body + '</div>');

    } catch (e) {
        console.error('[ERROR]', input, e);
    }
}

const args = process.argv.slice(2)
args.forEach(arg => {
    main(path.resolve(__dirname, arg))
})
Cyndaquil1999 commented 3 years ago

package-lock.json

{
  "requires": true,
  "lockfileVersion": 1,
  "dependencies": {
    "argparse": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
    },
    "entities": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
    },
    "esprima": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
    },
    "js-yaml": {
      "version": "3.14.1",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
      "requires": {
        "argparse": "^1.0.7",
        "esprima": "^4.0.0"
      },
      "dependencies": {
        "argparse": {
          "version": "1.0.10",
          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
          "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
          "requires": {
            "sprintf-js": "~1.0.2"
          }
        }
      }
    },
    "linkify-it": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz",
      "integrity": "sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==",
      "requires": {
        "uc.micro": "^1.0.1"
      }
    },
    "markdown-it": {
      "version": "12.1.0",
      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.1.0.tgz",
      "integrity": "sha512-7temG6IFOOxfU0SgzhqR+vr2diuMhyO5uUIEZ3C5NbXhqC9uFUHoU41USYuDFoZRsaY7BEIEei874Z20VMLF6A==",
      "requires": {
        "argparse": "^2.0.1",
        "entities": "~2.1.0",
        "linkify-it": "^3.0.1",
        "mdurl": "^1.0.1",
        "uc.micro": "^1.0.5"
      }
    },
    "markdown-it-meta": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/markdown-it-meta/-/markdown-it-meta-0.0.1.tgz",
      "integrity": "sha1-11to8RVlnK9WjkrUPLRgpHEkjDk=",
      "requires": {
        "js-yaml": "^3.8.1"
      }
    },
    "markdown-it-plantuml": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/markdown-it-plantuml/-/markdown-it-plantuml-1.4.1.tgz",
      "integrity": "sha512-13KgnZaGYTHBp4iUmGofzZSBz+Zj6cyqfR0SXUIc9wgWTto5Xhn7NjaXYxY0z7uBeTUMlc9LMQq5uP4OM5xCHg=="
    },
    "mdurl": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
      "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
    },
    "sprintf-js": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
    },
    "uc.micro": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
    }
  }
}
Cyndaquil1999 commented 3 years ago

お世話になっております。チームkstmです。

この問題ではindex.jsとconv.jsでのplantumlのサーバ設定が異なることが原因で発生したと考えられました。 そのため以下のように変更を行い、UML図が表示されることを確認いたしました。 確認のほどよろしくお願いします。

手順

現状問題であるのは画像ファイルの取得先であるhttps://www.plantuml.com/plantuml/{file_type}/{hogehoge}のドメインの部分の対応付けでありこちらを修正することで正しくUML図が表示されるような操作を以下にて行います。

1.index.jsの変更

index.jsの10行目のvar server = pluginOptions.server || 'https://www.plantuml.com/plantuml';var server = 'https://www.plantuml.com/plantuml';に変更します。

2.conv.jsの変更

conv.jsの15行目のserver: 'http://192.168.16.200:10080'server: 'https://www.plantuml.com/plantuml'に変更します。

このように操作するとsrcはhttps://www.plantuml.com/plantumlになりUML図が表示されています。

oyuyu-dev commented 3 years ago

https://www.plantuml.com/plantuml/{file_type}/{hogehoge}