사용자:BANIP/자동문서작성/플러그인

리버티게임, 모두가 만들어가는 자유로운 게임

/**

* 시간에 따라 바뀌는 유동적인 값을 반환합니다. cos함수, 혹은 그의 절대값 형태를 띕니다.
* @param start 최소값
* @param height 진폭
* @param wavelength 파장
* @param isAbs 절대값인가 아닌가
*/

var getFluidValue = function (start, height, wavelength, isAbs) {

   if (isAbs === void 0) { isAbs = true; }
   var now = Date.now() / Math.PI / wavelength;
   var amplitude = Math.cos(now) * height;
   return start + (isAbs ? Math.abs(amplitude) : amplitude);

}; /**

* 뷰에 해당하는 클래스, 캔버스와 연동해 노드들의 관계를 보여줌
*/

var GUI = /** @class */ (function () {

   /**
    * 생성자, 컨텍스트를 가져오기 위한 용도인 getcdtx를 정의
    * @param canvas 그림판으로 사용할 캔버스 객체
    */
   function GUI(canvas) {
       if (canvas === void 0) { canvas = document.querySelector("#nodemap"); }
       var _this = this;
       this.canvas = canvas;
       this.nodeCache = [];
       this.selectedNode = null;
       this.isUnlinkNode = false;
       this.dragInfo = null;
       /**
        * 캔버스에서 사용할 각종 수치
        */
       this.elemUnit = {
           wrap: {
               marginX: 50,
               marginY: 20
           },
           node: {
               intervalY: 20,
               width: 100,
               height: 50,
               getctx: null,
               selectNodeColor: "yellow"
           },
           branch: {
               width: 100,
               weight: 3,
               getctx: null
           }
       };
       this.elemUnit.node.getctx = function () {
           var ctx = _this.canvas.getContext("2d");
           ctx.textAlign = "center";
           ctx.textBaseline = "middle";
           ctx.font = "30px sans-serif";
           ctx.lineWidth = 5;
           ctx.setLineDash([]);
           ctx.strokeStyle = "black";
           return ctx;
       };
       this.elemUnit.branch.getctx = function () {
           var ctx = _this.canvas.getContext("2d");
           ctx.strokeStyle = "black";
           ctx.setLineDash([]);
           return ctx;
       };
   }
   /**
    * 특정 노드의 위치 획득
    * @param nodeList 위치를 획득할 노드가 속하는 집단
    * @param node 위치를 획득할 노드
    */
   GUI.prototype.getPosition = function (nodeList, node) {
       var thisPosition;
       nodeList.every(function (currentNode, i) {
           thisPosition = i;
           if (currentNode === node)
               return false;
           return true;
       });
       return thisPosition;
   };
   /**
    * 수정 대상이 될 노드 지정
    * @param node 수정 대상이 될 노드
    */
   GUI.prototype.nodeSelect = function (node, isUnlinkNode) {
       this.isUnlinkNode = isUnlinkNode;
       this.selectedNode = node;
   };
   GUI.prototype.getNodeByAxis = function (axis) {
       var _a = this.elemUnit, wrap = _a.wrap, node = _a.node, branch = _a.branch;
       var nodeContainerSize = node.intervalY + node.height;
       var isSafeX = axis.x >= branch.width + wrap.marginX && axis.x <= branch.width + wrap.marginX + node.width;
       if (!isSafeX)
           return null;
       var p = parseInt((axis.y - wrap.marginY) / nodeContainerSize + "");
       if (p === -1)
           return null;
       return this.nodeCache[p];
   };
   GUI.prototype.setNodeList = function (nodeList) {
       this.nodeCache = nodeList;
   };
   GUI.prototype.setDragInfo = function (axis) {
       this.dragInfo = axis;
   };
   /**
    * 캔버스에 출력
    */
   GUI.prototype.draw = function () {
       var _this = this;
       var nodeList = this.nodeCache;
       this.initCanvasSize(nodeList.length);
       nodeList.forEach(function (node, i) {
           _this.drawNode(node, i);
           node.getLinked().forEach(function (linkednode) {
               var j = _this.getPosition(nodeList, linkednode);
               _this.drawbranch(i, j);
           });
       });
       this.drawbranch(this.selectedNode, this.dragInfo, function () {
           var ctx = _this.elemUnit.branch.getctx();
           ctx.setLineDash([7, 3]);
           ctx.lineDashOffset = Date.now() / 100 % 100;
           ctx.strokeStyle = _this.isUnlinkNode ? "red" : "blue";
           return ctx;
       });
   };
   GUI.prototype.initCanvasSize = function (nodeCount) {
       var _a = this.elemUnit, wrap = _a.wrap, node = _a.node, branch = _a.branch;
       var width = wrap.marginX * 2 + node.width + branch.width * 2;
       var height = wrap.marginY * 2
           + (node.height * nodeCount)
           + node.intervalY * (nodeCount - 1);
       this.canvas.width = width;
       this.canvas.height = height;
   };
   GUI.prototype.getNodePosition = function (position, hori, vert) {
       if (hori === void 0) { hori = "left"; }
       if (vert === void 0) { vert = "top"; }
       var _a = this.elemUnit, wrap = _a.wrap, node = _a.node, branch = _a.branch;
       var getBonusWidth = function (hori) {
           if (hori == "left")
               return 0;
           if (hori == "center")
               return node.width / 2;
           if (hori == "right")
               return node.width;
       };
       var getBonusHeight = function (vert) {
           if (vert === "top")
               return 0;
           if (vert === "middle")
               return node.height / 2;
           if (vert === "bottom")
               return node.height;
       };
       return [
           wrap.marginX + branch.width + getBonusWidth(hori),
           wrap.marginY
               + (node.intervalY + node.height) * position
               + getBonusHeight(vert)
       ];
   };
   GUI.prototype.drawNode = function (node, position) {
       var nodeSize = this.elemUnit.node;
       var ctx = nodeSize.getctx();
       var axis = this.getNodePosition(position);
       if (node === this.selectedNode) {
           ctx.fillStyle = nodeSize.selectNodeColor;
           ctx.fillRect.apply(ctx, this.getNodePosition(position).concat([nodeSize.width, nodeSize.height]));
           ctx.fillStyle = "black";
       }
       ctx.strokeRect.apply(ctx, this.getNodePosition(position).concat([nodeSize.width, nodeSize.height]));
       ctx.fillText.apply(ctx, [node.getName()].concat(this.getNodePosition(position, "center", "middle")));
   };
   GUI.prototype.getBranchAxis = function (startPosition, endPosition) {
       var _this = this;
       var getAxisY = function (axis) {
           if (axis instanceof DocNode)
               axis = _this.getPosition(_this.nodeCache, axis);
           if (typeof axis == "number")
               return _this.getNodePosition(axis, "center", "middle")[1];
           return axis.y;
       };
       var _a = [getAxisY(startPosition), getAxisY(endPosition)], startAxisY = _a[0], endAxisY = _a[1];
       var direction = startAxisY > endAxisY ? "left" : "right";
       var isDirectionLeft = direction === "left";
       var axisX = this.getNodePosition(0, direction, "middle")[0];
       var start = [axisX, startAxisY];
       var end = [axisX, endAxisY];
       return [start, end];
   };
   GUI.prototype.drawbranch = function (startPosition, endPosition, getctx) {
       if (getctx === void 0) { getctx = this.elemUnit.branch.getctx; }
       if (startPosition === null || endPosition === null)
           return;
       var _a = this.getBranchAxis(startPosition, endPosition), start = _a[0], end = _a[1];
       var max = start[1] > end[1] ? end : start;
       var isDirectionLeft = max === end;
       var radius = Math.abs((end[1] - start[1]) / 2);
       var arrowSize = (isDirectionLeft ? -1 : 1) * 15;
       var ctx = getctx();
       ctx.beginPath();
       ctx.arc(max[0], max[1] + radius, radius, isDirectionLeft ? Math.PI * 1 / 2 : Math.PI * 3 / 2, isDirectionLeft ? Math.PI * 3 / 2 : Math.PI * 1 / 2);
       ctx.moveTo.apply(ctx, end);
       ctx.lineTo(end[0] + arrowSize, end[1] + arrowSize);
       ctx.moveTo.apply(ctx, end);
       ctx.lineTo(end[0] + arrowSize, end[1] - arrowSize);
       ctx.stroke();
   };
   return GUI;

}()); var NodeInput = /** @class */ (function () {

   function NodeInput(gui, nodeList) {
       if (gui === void 0) { gui = new GUI(); }
       this.gui = gui;
       this.nodeList = nodeList;
       this.selectedNode = null;
       this.$$ = document.querySelector.bind(document);
       this.initEventListener();
       this.initCanvasEventListener();
   }
   NodeInput.prototype.initEventListener = function () {
       var _this = this;
       var $$ = this.$$;
       // addNode
       var addNodeListener = function (e) {
           var nodenameNode = $$(".inp_addnodename");
           var nodeName = nodenameNode.value;
           nodenameNode.value = "";
           _this.nodeList.addNode(nodeName);
       };
       $$(".btn_addnode").addEventListener("click", addNodeListener);
       $$(".inp_addnodename").addEventListener("keydown", function (e) {
           if (e.key === "Enter") {
               addNodeListener(e);
           }
       });
       $$(".btn_removenode").addEventListener("click", function (e) {
           if (_this.selectedNode === null)
               throw Error("삭제할 노드를 선택 해 주세요.");
           _this.nodeList.removeNode(_this.selectedNode.getName());
           var lastNode = _this.nodeList.getNodeList().slice(-1)[0];
           console.log(lastNode);
           _this.gui.nodeSelect(lastNode, false);
           _this.selectedNode = lastNode;
       });
       var createDocListener = function (e) {
           var sendMessage = function (message) { return $$(".btn_create_message").innerHTML = message; };
           $$(".btn_create_create").removeEventListener("click", createDocListener);
           sendMessage("문서 생성 요청을 보냈습니다. 준비할때까지 좀만 기다려주세요");
           var prefix = $$(".inp_create_target").value;
           var template = $$(".inp_create_form").value;
           if (prefix.slice(-1) !== "/")
               prefix += "/";
           DocFactory.create(_this.nodeList, template, prefix, sendMessage);
       };
       $$(".btn_create_create").addEventListener("click", createDocListener);
   };
   NodeInput.prototype.initCanvasEventListener = function () {
       var _this = this;
       var $$ = this.$$;
       var getAxis = function (e) { return ({ x: e.offsetX, y: e.offsetY }); };
       var setSelectedNode = function (node, isUnlinkMode) {
           _this.selectedNode = node;
           _this.setSelectedNode(node);
           _this.gui.nodeSelect(_this.selectedNode, isUnlinkMode);
       };
       var isMouseDown = false;
       // selectNode
       $$("#nodemap").addEventListener("mousedown", function (e) {
           var axis = getAxis(e);
           isMouseDown = true;
           setSelectedNode(_this.gui.getNodeByAxis(axis), e.button == 2);
       });
       // searchTarget
       $$("#nodemap").addEventListener("mousemove", function (e) {
           if (isMouseDown === false)
               return _this.gui.setDragInfo(null);
           ;
           var axis = getAxis(e);
           _this.gui.getNodeByAxis(axis);
           _this.gui.setDragInfo(axis);
       });
       // setTarget
       $$("#nodemap").addEventListener("mouseup", function (e) {
           var selectedNode = _this.selectedNode;
           isMouseDown = false;
           var axis = getAxis(e);
           var throwNode = _this.gui.getNodeByAxis(axis);
           if (selectedNode === null || throwNode === null)
               return;
           if (e.button == 0) {
               _this.nodeList.linkNode(throwNode.getName(), selectedNode.getName());
           }
           else if (e.button == 2) {
               _this.nodeList.unLinkNode(throwNode.getName(), selectedNode.getName());
           }
       });
       // removePreventEvent
       $$("#nodemap").addEventListener("contextmenu", function (e) {
           e.preventDefault();
       });
   };
   NodeInput.prototype.setSelectedNode = function (node) {
       var $$ = this.$$;
       this.selectedNode = node;
       $$(".spn_nodename").innerHTML = node.getName();
   };
   return NodeInput;

}()); var DocFactory = /** @class */ (function () {

   function DocFactory() {
   }
   DocFactory.setTemplateVariable = function (template, templateVariable) {
       var _a = templateVariable.shift(), searchValue = _a[0], replaceValue = _a[1];
       template = template.replace("{[" + searchValue + "]}", replaceValue);
       if (templateVariable.length != 0)
           return DocFactory.setTemplateVariable(template, templateVariable);
       return template;
   };
   DocFactory.setLinkNoding = function (node, template, prefix) {
       var nodeName = node.getName();
       return template.replace(/\{\[링크\|([^]+)\]\}/g, function (matchedStr) {
           matchedStr = matchedStr.replace(/\{\[링크\|\s*([^]+)\s*\]\}/g, "$1");
           return node.getLinked().map(function (linkedNode) {
               var templateVariable = [
                   ["링크노드네임", linkedNode.getName()],
                   ["링크페이지네임", prefix + linkedNode.getName()]
               ];
               return DocFactory.setTemplateVariable(matchedStr, templateVariable.slice());
           }).join("\n");
       });
   };
   DocFactory.setOtherVariable = function (node, template, prefix) {
       var nodeName = node.getName();
       var templateVariable = [
           ["노드네임", nodeName],
           ["페이지네임", prefix + nodeName]
       ];
       return DocFactory.setTemplateVariable(template, templateVariable);
   };
   DocFactory.create = function (docNodeList, template, prefix, messageCallback) {
       var nodeList = docNodeList.getNodeList();
       var docQueue = nodeList.map(function (node) {
           var docString = template;
           var nodeName = node.getName();
           docString = DocFactory.setLinkNoding(node, docString, prefix);
           docString = DocFactory.setOtherVariable(node, docString, prefix);
           return { title: prefix + nodeName, content: docString };
       });
       DocFactory.makeDoc(messageCallback, docQueue);
   };
   DocFactory.makeDoc = function (messageCallback, docQueue) {
       var api = MediaWikiAPI();
       var makeDocIntervar = setInterval(function () {
           if (docQueue.length === 0) {
               messageCallback("\uBAA8\uB4E0 \uBB38\uC11C\uB97C \uC791\uC131\uD588\uC2B5\uB2C8\uB2E4. \uCD5C\uADFC \uBC14\uB01C\uC744 \uD655\uC778 \uD574 \uC8FC\uC2ED\uC1FC");
               clearInterval(makeDocIntervar);
           }
           var nextDoc = docQueue.pop();
           api.changeDocument(nextDoc.title, "템플릿 문서작성 스크립트 실행중", nextDoc.content, true);
           messageCallback("\uBB38\uC11C\uB97C \uBAA8\uB450 \uC791\uC131\uD558\uAE30\uAE4C\uC9C0 \uC55E\uC73C\uB85C " + docQueue.length + "\uAC1C \uB0A8\uC558\uC2B5\uB2C8\uB2E4.");
       }, 3000);
   };
   return DocFactory;

}()); var DocNodeList = /** @class */ (function () {

   function DocNodeList(gui) {
       if (gui === void 0) { gui = new GUI(); }
       this.gui = gui;
       this.nodeList = {};
   }
   DocNodeList.prototype.sendDraw = function () {
       this.gui.setNodeList(Object.values(this.nodeList));
   };
   DocNodeList.prototype.hasNotNode = function (node) {
       return typeof node === "undefined";
   };
   DocNodeList.prototype.linkNode = function (forNodename, toNodename) {
       var _a = this, hasNotNode = _a.hasNotNode, nodeList = _a.nodeList;
       var forNode = nodeList[forNodename];
       var toNode = nodeList[toNodename];
       if (hasNotNode(forNode) || hasNotNode(toNode))
           throw Error("존재하지 않는 노드입니다.");
       toNode.link(forNode);
       this.sendDraw();
   };
   DocNodeList.prototype.unLinkNode = function (forNodename, toNodename) {
       if (toNodename === void 0) { toNodename = null; }
       var _a = this, hasNotNode = _a.hasNotNode, nodeList = _a.nodeList;
       var forNode = nodeList[forNodename];
       var toNode = nodeList[toNodename];
       if (hasNotNode(forNode))
           throw Error("존재하지 않는 노드입니다.");
       if (hasNotNode(toNodename)) {
           this.getNodeList().forEach(function (currentNode) {
               currentNode.unLink(forNode);
               forNode.unLink(currentNode);
           });
       }
       else {
           toNode.unLink(forNode);
       }
       this.sendDraw();
   };
   DocNodeList.prototype.addNode = function (nodename) {
       var nodeList = this.nodeList;
       if (nodeList[nodename] instanceof Node)
           throw Error("이미 존재하는 노드입니다");
       else {
           nodeList[nodename] = new DocNode(nodename);
           this.sendDraw();
       }
   };
   DocNodeList.prototype.removeNode = function (nodename) {
       var nodeList = this.nodeList;
       var targetNode = nodeList[nodename];
       if (this.hasNotNode(targetNode))
           throw Error("존재하지 않는 노드입니다.");
       delete nodeList[nodename];
       this.getNodeList().forEach(function (node) { return node.unLink(targetNode); });
       this.sendDraw();
   };
   DocNodeList.prototype.getNodeList = function () { return Object.values(this.nodeList); };
   return DocNodeList;

}()); var DocNode = /** @class */ (function () {

   function DocNode(name) {
       this.name = name;
       this.linkedNode = [];
   }
   DocNode.prototype.link = function (node) {
       if (node === this)
           return; //throw Error("연결하려는 노드가 자신입니다.");
       if (this.linkedNode.some(function (currentNode) { return currentNode === node; }))
           throw Error("이미 연결된 노드입니다.");
       this.linkedNode.push(node);
   };
   DocNode.prototype.unLink = function (node) {
       var _this = this;
       this.linkedNode.forEach(function (currentNode, i) {
           if (currentNode === node)
               _this.linkedNode.splice(i, 1);
       });
   };
   DocNode.prototype.getLinked = function () {
       return this.linkedNode;
   };
   DocNode.prototype.getName = function () { return this.name; };
   DocNode.prototype.setName = function (name) { return this.name = name; };
   return DocNode;

}()); var initHTML = function () {

$("#content").append(`

<section class="section_node">\n <canvas id="nodemap"></canvas>\n</section>\n<section class="section_node">\n

노드 스케치 조작법

\n
    \n
  • 노드 선택: 선택하고 싶은 노드 클릭
  • \n
  • 노드 링킹: 링크하고 싶은 노드 클릭 후 링크 대상이 되는 노드에 갖다 끌기
  • \n
  • 노드 링킹 해제: 해제하고 싶은 노드 클릭 후 링크 대상이 되는 노드에 갖다 끌기
  • \n
\n

새로운 노드 추가

\n 노드 이름 <input class="inp_addnodename"/> <button class="btn_addnode" placeholder="노드의 제목을 입력해주세요..." > 추가 </button>\n

기존 노드 수정

\n 현재 선택된 노드: 선택되지 않음 \n <button class="btn_removenode"> 노드 삭제 </button> \n\n

노드 작성 완료 및 문서 생성

\n
\n  아래 텍스트 에리어에 각 문서에 생성될 템플릿을 입력 해 주세요. 템플릿에서 사용 가능한 특수 문법은 다음과 같습니다.\n  {[노드네임]} : 노드 이름을 출력합니다.\n  {[페이지네임]} : 페이지 이름을 출력합니다.\n  {[링크| .... ]} : 다른 노드와 링크된 갯수만큼 파라미터 안의 내용을 반복합니다.\n  {[링크노드네임]} : 링크함수 내부에 쓰이는 변수입니다. 링크된 노드의 이름을 출력합니다.\n  {[링크페이지네임]} : 링크함수 내부에 쓰이는 변수입니다. 링크된 페이지의 이름을 출력합니다.\n  
\n 최상위 문서 제목<input class="inp_create_target" value="사용자:BANIP/자동문서작성/플러그인/테스트" size="40" />\n\n <textarea class="inp_create_form"> \n현재역은 {[노드네임]}입니다.\n== 선택지 ==\n{[링크|\n* [[{[링크페이지네임]}|{[링크노드네임]}역으로]]\n]}\n </textarea>\n <button class="btn_create_create"> 생성 </button>\n
문서를 생성할 준비가 다 되었으면 위 버튼 눌러주세요
\n</section>

`);

}; var test = (function () {

   initHTML();
   var gui = new GUI();
   var nodeList = new DocNodeList(gui);
   var nodeInput = new NodeInput(gui, nodeList);
   nodeList.addNode("서울");
   nodeList.addNode("부산");
   nodeList.addNode("인천");
   nodeList.addNode("대구");
   nodeList.linkNode("서울", "부산");
   nodeList.linkNode("서울", "인천");
   nodeList.linkNode("서울", "대구");
   nodeList.linkNode("대구", "부산");
   setInterval(function () { return gui.draw(); }, 50);
   //nodeList.removeNode("미남")

})();