Created
February 27, 2020 00:31
-
-
Save sremy/2b68d5c8370eac3f145aac1ef8b5811e to your computer and use it in GitHub Desktop.
File -> Parser -> Graph!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function dropHandler(ev) { | |
| ev.target.classList.remove("over_zone"); | |
| // Prevent default behavior (Prevent file from being opened) | |
| ev.preventDefault(); | |
| if (ev.dataTransfer.items) { | |
| // Use DataTransferItemList interface to access the file(s) | |
| // console.log(ev.dataTransfer) | |
| for (var i = 0; i < ev.dataTransfer.items.length; i++) { | |
| // If dropped items aren't files, reject them | |
| if (ev.dataTransfer.items[i].kind === 'file') { | |
| var file = ev.dataTransfer.items[i].getAsFile(); | |
| console.log('... file[' + i + '].name = ' + file.name + ' ' + file.size + ' bytes'); | |
| readFile(file); | |
| } | |
| } | |
| } else { | |
| // Use DataTransfer interface to access the file(s) | |
| for (var i = 0; i < ev.dataTransfer.files.length; i++) { | |
| console.log('... file[' + i + '].name = ' + ev.dataTransfer.files[i].name + ' ' + file.size + ' bytes'); | |
| readFile(file); | |
| } | |
| } | |
| } | |
| function readFile(file) { | |
| var reader = new FileReader(); | |
| var content = document.getElementById('drop_zone'); | |
| reader.onload = function (event) { | |
| clearGraph(); | |
| fileContent = event.target.result | |
| content.innerHTML = 'Filename: ' + file.name; | |
| content.innerHTML += '<br/>Size: ' + fileContent.length + ''; | |
| parseHiera(fileContent) | |
| }; | |
| reader.readAsText(file); | |
| } | |
| function parseHiera(hieratxt) { | |
| console.log('Parsing text of length ' + hieratxt.length) | |
| let myReader = new Reader(); | |
| let racineNode = myReader.readFile(hieratxt)['racine']; | |
| displayGraph(racineNode); | |
| } | |
| function dragOverHandler(ev) { | |
| ev.dataTransfer.dropEffect = 'copy'; | |
| ev.target.classList.add("over_zone"); | |
| ev.preventDefault(); | |
| } | |
| function dragLeaveHandler(ev) { | |
| ev.target.classList.remove("over_zone"); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var treemap = d3.treemap(); | |
| //d3 = require("d3@5", "d3-array@2") | |
| dx = 30 | |
| dy = 160 | |
| // width = 954 | |
| tree = d3.tree().nodeSize([dx, dy]) | |
| treeLink = d3.linkHorizontal().x(d => d.y).y(d => d.x) | |
| function graph(root, { | |
| label = d => d.data.label + ' (' + (d.data.price ? d.data.price : '') + ')', | |
| highlight = () => false, | |
| marginLeft = 100 | |
| } = {}) { | |
| root = tree(root); | |
| console.log('root.descendants()=' + root.descendants()) | |
| console.log(root.descendants()) | |
| let x0 = Infinity; | |
| let x1 = -x0; | |
| root.each(d => { | |
| if (d.x > x1) x1 = d.x; // max | |
| if (d.x < x0) x0 = d.x; // min | |
| }); | |
| let y0 = Infinity; | |
| let y1 = -y0; | |
| root.each(d => { | |
| if (d.y > y1) y1 = d.y; // max | |
| if (d.y < y0) y0 = d.y; // min | |
| }); | |
| // console.log("x1 " + x1 + " x0 " + x0); | |
| // console.log("y1 " + y1 + " y0 " + y0); | |
| width = y1 - y0 + dy * 2; | |
| height = x1 - x0 + dx * 2; | |
| const svg = d3.select("svg") | |
| .attr("width", width) | |
| .attr("height", height) | |
| // .attr("viewBox", [0, 0, width, x1 - x0 + dx * 2]) | |
| .style("overflow", "visible"); | |
| const g = svg.append("g") | |
| .attr("font-family", "sans-serif") | |
| .attr("font-size", 14) | |
| .attr("transform", `translate(${marginLeft}, ${dx - x0})`); | |
| const link = g.append("g") | |
| .attr("fill", "none") | |
| .attr("stroke", "#555") | |
| .attr("stroke-opacity", 0.5) | |
| .attr("stroke-width", 1.5) | |
| .selectAll("path") | |
| .data(root.links()) | |
| .join("path") | |
| .attr("stroke", d => highlight(d.source) && highlight(d.target) ? "red" : null) | |
| .attr("stroke-opacity", d => highlight(d.source) && highlight(d.target) ? 1 : null) | |
| .attr("d", treeLink); | |
| const node = g.append("g") | |
| .attr("stroke-linejoin", "round") | |
| .attr("stroke-width", 3) | |
| .selectAll("g") | |
| .data(root.descendants()) | |
| .join("g") | |
| .attr("transform", d => `translate(${d.y},${d.x})`); | |
| node.append("circle") | |
| .attr("fill", d => highlight(d) ? "red" : d.children ? "#955" : "#559") | |
| .attr("r", 2.5); | |
| textlabel = node.append("text") | |
| .attr("fill", d => highlight(d) ? "red" : null) | |
| .attr("dy", "0.31em") | |
| .attr("x", d => d.children ? -6 : 6) | |
| .attr("text-anchor", d => d.children ? "end" : "start") | |
| .text(label); | |
| textlabel.clone(true).lower() | |
| .attr("stroke", "white") | |
| .attr("stroke-width", "5"); | |
| textlabel.append("tspan") | |
| .attr("x", d => d.children ? -6 : 6) | |
| .attr("dy", "1.2em") | |
| .attr("fill", "blue") | |
| .text(d => d.data.price) | |
| return svg.node(); | |
| } | |
| //familyChart = graph(hiera, {label: d => d.data.name, highlight: (d) => d.name === "Abel" || d.name === "Eve"}) | |
| // --------------------------------------------- | |
| function contractsChildrenFunction(node) { | |
| return node.contract_list; | |
| } | |
| function displayGraph(racineNode) { | |
| console.log(racineNode); | |
| hiera = d3.hierarchy(racineNode, contractsChildrenFunction); | |
| console.log(hiera); | |
| hieraChart = graph(hiera); | |
| } | |
| function clearGraph() { | |
| document.getElementById("graph-hiera").innerHTML = ''; | |
| } | |
| function testGraph() { | |
| let racineNode = testReader(); | |
| displayGraph(racineNode); | |
| } | |
| // testGraph(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Parser page</title> | |
| <!--link rel="stylesheet" href="style.css"--> | |
| <script src="./parser.js"></script> | |
| <script src="./reader.js"></script> | |
| <script src="https://d3js.org/d3.v5.min.js"></script> | |
| <style> | |
| .drop_zone { | |
| border: 3px solid rgb(173, 173, 224); | |
| /* box-sizing: border-box; */ | |
| z-index: -1; | |
| position: fixed; | |
| width: -3; | |
| height: -3; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| font: caption; | |
| font-size: 14px; | |
| } | |
| .over_zone { | |
| border: 6px solid darkblue; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- page content --> | |
| <svg id="graph-hiera" ></svg> | |
| <div id="drop_zone" class="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);" ondragleave="dragLeaveHandler(event)"> | |
| <p>Drag one file to draw hierarchy tree...</p> | |
| </div> | |
| </body> | |
| <script src="./hiera.js"></script> | |
| <script src="./dropfile.js"></script> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Token { | |
| chaine = ''; | |
| tokenType = null; | |
| constructor(type, chaine) { | |
| this.tokenType = type; | |
| this.chaine = chaine; | |
| } | |
| } | |
| class Parser { | |
| curToken = Parser.nodes.START; | |
| cursor = 0; | |
| constructor(texte) { | |
| this.texte = texte; | |
| } | |
| parse() { | |
| if(this.isEnd()) { | |
| this.curToken = Parser.nodes.END; | |
| return new Token(Parser.nodes.END, ''); | |
| } | |
| switch(this.curToken) { | |
| case Parser.nodes.STRINGEND: // eat ';' | |
| case Parser.nodes.NUMBEREND: | |
| case Parser.nodes.VALUECLOSEARRAY: | |
| this.consumeSemiColon(); | |
| case Parser.nodes.START: | |
| return new Token(Parser.nodes.LABEL1, this.consumeLabel()); | |
| case Parser.nodes.LABEL1: | |
| return new Token(Parser.nodes.LABEL1, this.consumeLabel()); | |
| case Parser.nodes.LABEL2: | |
| return new Token(Parser.nodes.LABEL2, this.consumeLabel()); | |
| case Parser.nodes.FIELDNAME: | |
| return new Token(Parser.nodes.FIELDNAME, this.consumeLabel()); | |
| case Parser.nodes.AFFECTATION: | |
| return this.parseValue(); | |
| case Parser.nodes.VALUEOPENARRAY: | |
| return this.parseArray(); | |
| case Parser.nodes.STRINGARRAY: | |
| case Parser.nodes.NUMBERARRAY: | |
| return this.parseInsideArray(); | |
| case Parser.nodes.END: | |
| return new Token(Parser.nodes.END, ''); | |
| } | |
| return Parser.nodes.START; | |
| } | |
| isEnd() { | |
| return this.cursor >= this.texte.length; | |
| } | |
| consumeLabel() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.skipSpaceAndEOL() || this.detectComments()) continue; | |
| else if(this.texte[this.cursor] === ':' && this.cursor+1 < this.texte.length && this.texte[this.cursor+1] === '=') { // WARN check size buffer | |
| this.curToken = Parser.nodes.AFFECTATION; | |
| this.cursor+=2; | |
| return chaine; | |
| } | |
| else if(this.texte[this.cursor] === '.') { | |
| this.curToken = Parser.nodes.LABEL2; | |
| this.cursor++; | |
| return chaine; | |
| } | |
| else if(this.texte[this.cursor] === '/') { | |
| this.curToken = Parser.nodes.FIELDNAME; | |
| this.cursor++; | |
| return chaine; | |
| } | |
| else { | |
| chaine += this.texte[this.cursor]; | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| consumeString() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.texte[this.cursor] === '"') { | |
| this.cursor++; | |
| this.curToken = Parser.nodes.STRINGEND; | |
| return chaine; | |
| } | |
| else if(this.texte[this.cursor] === '\\' && this.cursor+1 < this.texte.length && this.texte[this.cursor+1] === '"') { | |
| chaine += '"'; | |
| this.cursor += 2; | |
| } | |
| else { | |
| chaine += this.texte[this.cursor]; | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| consumeNumber() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.texte[this.cursor] <= '9' && this.texte[this.cursor] >= '0') { | |
| chaine += this.texte[this.cursor++]; | |
| } | |
| else if(this.texte[this.cursor] === '.' || this.texte[this.cursor] === 'e' || | |
| this.texte[this.cursor] === 'E' || this.texte[this.cursor] === '-') { | |
| chaine += this.texte[this.cursor++]; | |
| } | |
| else if(this.texte[this.cursor] === ' ') { | |
| this.cursor++; | |
| this.curToken = Parser.nodes.NUMBEREND; | |
| return chaine; | |
| } | |
| else { // especially ';' | |
| this.curToken = Parser.nodes.NUMBEREND; | |
| return chaine; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| parseValue() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.skipSpaceAndEOL() || this.detectComments()) continue; | |
| if(this.texte[this.cursor] === '"') { | |
| this.cursor++; | |
| return new Token(Parser.nodes.VALUESTRING, this.consumeString()); | |
| } | |
| else if((this.texte[this.cursor] <= '9' && this.texte[this.cursor] >= '0') | |
| || (this.texte[this.cursor] === '-' && this.texte[this.cursor+1] !== '-')) { | |
| return new Token(Parser.nodes.VALUENUMBER, this.consumeNumber()); | |
| } | |
| else if(this.texte[this.cursor] === '[' || this.texte[this.cursor] === '(') { | |
| this.curToken = Parser.nodes.VALUEOPENARRAY; | |
| return new Token(Parser.nodes.VALUEOPENARRAY, this.texte[this.cursor++]); | |
| } | |
| else { | |
| console.warn('Unexpected character [' + this.texte[this.cursor] + '], value expected'); | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| // After parsing '[' character | |
| parseArray() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.skipSpaceAndEOL() || this.detectComments()) continue; | |
| if(this.texte[this.cursor] === '"') { | |
| this.cursor++; | |
| const stringToken = new Token(Parser.nodes.VALUESTRING, this.consumeString()); | |
| this.curToken = Parser.nodes.STRINGARRAY; | |
| return stringToken; | |
| } | |
| else if((this.texte[this.cursor] <= '9' && this.texte[this.cursor] >= '0') | |
| || (this.texte[this.cursor] === '-' && this.texte[this.cursor+1] !== '-')) { | |
| const numberToken = new Token(Parser.nodes.VALUENUMBER, this.consumeNumber()); | |
| this.curToken = Parser.nodes.NUMBERARRAY; | |
| return numberToken; | |
| } | |
| else if(this.texte[this.cursor] === ']' || this.texte[this.cursor] === ')') { | |
| this.curToken = Parser.nodes.VALUECLOSEARRAY; | |
| return new Token(Parser.nodes.VALUECLOSEARRAY, this.texte[this.cursor++]); | |
| } | |
| else { | |
| console.warn('Unexpected character [' + this.texte[this.cursor] + '] ' + this.texte.charCodeAt(this.cursor) + ', array element expected'); | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| // After parsing an element in array, expect: ',' or ']' | |
| parseInsideArray() { | |
| while(!this.isEnd()) { | |
| if(this.skipSpaceAndEOL() || this.detectComments()) continue; | |
| if(this.texte[this.cursor] === ',') { | |
| this.cursor++; | |
| this.curToken = Parser.nodes.VALUEOPENARRAY; | |
| return this.parseArray(); | |
| } | |
| else if(this.texte[this.cursor] === ']' || this.texte[this.cursor] === ')') { | |
| this.curToken = Parser.nodes.VALUECLOSEARRAY; | |
| return new Token(Parser.nodes.VALUECLOSEARRAY, this.texte[this.cursor++]); | |
| } | |
| else { | |
| console.warn('Unexpected character: ' + this.texte[this.cursor]); | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return ''; | |
| } | |
| // End of statement, Nothing else than semicolon, comment and spaces is expected | |
| consumeSemiColon() { | |
| let chaine = ''; | |
| while(!this.isEnd()) { | |
| if(this.skipSpaceAndEOL() || this.detectComments()) continue; | |
| if(this.texte[this.cursor] === ';') { | |
| this.curToken = Parser.nodes.START; | |
| this.cursor++; | |
| return ';'; | |
| } | |
| else { | |
| console.warn('Unexpected character after statement: [' + this.texte[this.cursor] + '] expected ";"') | |
| chaine += this.texte[this.cursor]; | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return chaine; | |
| } | |
| skipSpaceAndEOL() { | |
| if(this.texte[this.cursor] === ' ' || this.texte[this.cursor] === '\r' | |
| || this.texte[this.cursor] === '\n' || this.texte[this.cursor] === '\t') { | |
| this.cursor++; | |
| return true; | |
| } | |
| } | |
| detectComments() { | |
| if(this.texte[this.cursor] === '-' && this.cursor+1 < this.texte.length && this.texte[this.cursor+1] === '-') { | |
| this.cursor+=2; | |
| this.eatComments(); | |
| return true; | |
| } | |
| } | |
| eatComments() { | |
| while(!this.isEnd()) { | |
| if(this.texte[this.cursor] === '\r' && this.cursor+1 < this.texte.length && this.texte[this.cursor+1] === '\n') { | |
| this.curToken = Parser.nodes.START; | |
| this.cursor+=2; | |
| return; | |
| } | |
| else if(this.texte[this.cursor] === '\n') { | |
| this.curToken = Parser.nodes.START; | |
| this.cursor++; | |
| return; | |
| } | |
| else { | |
| this.cursor++; | |
| } | |
| } | |
| this.curToken = Parser.nodes.END; | |
| return; | |
| } | |
| } | |
| Parser.nodes = { | |
| START: 'START', | |
| LABEL1: 'LABEL1', | |
| LABEL2: 'LABEL2', | |
| FIELDNAME: 'FIELDNAME', | |
| AFFECTATION: 'AFFECTATION', | |
| VALUESTRING: 'VALUESTRING', | |
| STRINGEND: 'STRINGEND', | |
| VALUENUMBER: 'VALUENUMBER', | |
| NUMBEREND: 'NUMBEREND', | |
| VALUEOPENARRAY: 'VALUEOPENARRAY', | |
| STRINGARRAY: 'STRINGARRAY', | |
| NUMBERARRAY: 'NUMBERARRAY', | |
| VALUECLOSEARRAY: 'VALUECLOSEARRAY', | |
| COMMENT: 'COMMENT', | |
| END: 'END' | |
| }; | |
| function testParser() { | |
| let myparser = new Parser(`result := "racine" ; -- plop | |
| racine.contract_list := ["contrat1", "contrat2", -- this is a comment in array | |
| "contrat4", "contrat10" ] ; | |
| racine.contract_size := 4; | |
| racine.contrat1/contract_list := [ "subcontrat11" ]; | |
| racine.contrat2/contract_list := [15, 0.123, -7894, 1.5e3];`); | |
| // let myparser = new Parser('result := "racine" ; \ | |
| // \ | |
| // racine.contract_size := 4;\ | |
| // racine.number := 0.123 ;\ | |
| // racine.contrat1/contract_list := "a sub contrat11"; \ | |
| // racine.contrat2/contract_list := "subcontrat21";'); | |
| let token = null; | |
| let i = 0; | |
| while((token === null || token.tokenType !== 'end') && i < 50) { | |
| token = myparser.parse(); | |
| console.log(token.tokenType + '[' + token.chaine + '] ' + ' @' + myparser.cursor + ' -> ' + myparser.curToken); | |
| i++; | |
| } | |
| } | |
| //testParser(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Reader { | |
| setValueInDico(value) { | |
| if(this.fieldName !== '') { | |
| const key = this.label + '.' + this.label2; | |
| if(this.dico[key] === undefined) { | |
| this.dico[key] = {}; | |
| } | |
| this.dico[key][this.fieldName] = value; | |
| } | |
| else if (this.label2 !== '') { | |
| if(this.dico[this.label] === undefined) { | |
| this.dico[this.label] = {}; | |
| } | |
| this.dico[this.label][this.label2] = value; | |
| } | |
| else { | |
| this.dico[this.label] = value; | |
| } | |
| this.label = this.label2 = this.fieldName = ''; | |
| } | |
| dico = {}; | |
| label = ''; | |
| label2 = ''; | |
| fieldName = ''; | |
| arrayValue = null; | |
| init() { | |
| this.dico = {}; | |
| this.label = ''; | |
| this.label2 = ''; | |
| this.fieldName = ''; | |
| this.arrayValue = null; | |
| } | |
| readFile(texte) { | |
| this.init(); | |
| let myparser = new Parser(texte); | |
| let token = null; | |
| let i = 0; | |
| while((token === null || token.tokenType !== Parser.nodes.END) && i++ < texte.length) { | |
| token = myparser.parse(); | |
| // console.log(token.tokenType + '[' + token.chaine + '] ' + ' @' + myparser.cursor + ' -> ' + myparser.curToken); | |
| switch(token.tokenType) { | |
| case Parser.nodes.LABEL1: | |
| this.label = token.chaine; | |
| break; | |
| case Parser.nodes.LABEL2: | |
| this.label2 = token.chaine; | |
| break; | |
| case Parser.nodes.FIELDNAME: | |
| this.fieldName = token.chaine; | |
| break; | |
| case Parser.nodes.VALUENUMBER: | |
| if(this.arrayValue === null) { | |
| this.setValueInDico(token.chaine); | |
| } | |
| else { | |
| this.arrayValue.push(token.chaine); | |
| } | |
| break; | |
| case Parser.nodes.VALUESTRING: | |
| if(this.arrayValue === null) { | |
| this.setValueInDico(token.chaine); | |
| } | |
| else { | |
| this.arrayValue.push(token.chaine); | |
| } | |
| break; | |
| case Parser.nodes.VALUEOPENARRAY: | |
| this.arrayValue = []; | |
| break; | |
| case Parser.nodes.NUMBERARRAY: // not used | |
| this.arrayValue.push(token.chaine); | |
| console.log('NUMBERARRAY arrayValue = ' + this.arrayValue); | |
| break; | |
| case Parser.nodes.STRINGARRAY: // not used | |
| this.arrayValue.push(token.chaine); | |
| console.log('STRINGARRAY arrayValue = ' + this.arrayValue); | |
| break; | |
| case Parser.nodes.VALUECLOSEARRAY: | |
| this.setValueInDico(this.arrayValue); | |
| this.arrayValue = null; | |
| break; | |
| case Parser.nodes.END: | |
| break; | |
| default: | |
| console.warn('Unexpected token ' + token.tokenType + ': [' + token.chaine + ']') | |
| } | |
| } | |
| this.traverse(this.dico['racine']); | |
| // console.log(this.dico); | |
| return this.dico; | |
| } | |
| // unused | |
| process(key, value) { | |
| if(key === 'contract_list') { | |
| //console.log(key + " : " + value); | |
| value.forEach(c => console.log(this.dico['racine.' + c])); | |
| } | |
| } | |
| traverse(obj) { | |
| for (let prop in obj) { | |
| // func.apply(this, [prop, obj[prop]]); | |
| if(prop === 'contract_list') { | |
| // console.log(obj); | |
| let liste = obj[prop]; | |
| for(let i = 0; i < liste.length; i++) { | |
| let referenceName = liste[i]; | |
| if(typeof(referenceName) === 'string') { | |
| // console.log('key: ' + 'racine.' + referenceName); | |
| liste[i] = this.dico['racine.' + referenceName]; | |
| } | |
| } | |
| } | |
| // TODO restrict to list or contract_list ? | |
| if (obj[prop] !== null && typeof (obj[prop]) == "object") { | |
| this.traverse(obj[prop]); // recursive call | |
| } | |
| } | |
| } | |
| } | |
| function testReader() { | |
| const contractHieraTexte = `result := "racine" ; -- plop | |
| racine.contract_list := ["contrat1", "contrat2", -- this is a comment in array | |
| "contrat4", "contrat9" ] ; | |
| racine.label := "The Racine"; | |
| racine.contract_size := 4; | |
| racine.totalprice := 12.123; | |
| racine.product/label := "a quality product"; | |
| racine.product/price := 9565.90; | |
| racine.product/origin := "Finistère"; | |
| racine.contrat1/price_list := [15, 0.123, -7894, 1.5e3]; | |
| racine.contrat1/contract_list := [ "subcontrat11" ]; | |
| racine.contrat2/contract_list := ["subcontrat21"]; | |
| racine.contrat4/contract_list := ["subcontrat41"]; | |
| racine.contrat9/contract_list := ["subcontrat91"]; | |
| racine.contrat1/label := "contrat 1"; | |
| racine.contrat2/label := "contrat 2"; | |
| racine.contrat3/label := "contrat 3"; | |
| racine.contrat4/label := "contrat 4"; | |
| racine.contrat9/label := "contrat 9"; | |
| racine.contrat1/price := "9.9€"; | |
| racine.contrat2/price := "11€"; | |
| racine.contrat3/price := "12€"; | |
| racine.contrat4/price := "13€"; | |
| racine.contrat9/price := "20€"; | |
| racine.subcontrat11/label := "label contrat 11"; | |
| racine.subcontrat11/name := "name contrat 11"; | |
| racine.subcontrat11/price := "111$"; | |
| racine.subcontrat21/label := "contrat 21"; | |
| racine.subcontrat21/contract_list := ["subsubcontrat211"]; | |
| racine.subcontrat41/label := "contrat 41"; | |
| racine.subcontrat91/label := "contrat 91"; | |
| racine.subcontrat91/price := "321£"; | |
| racine.subsubcontrat211/label := "contrat 211"; | |
| racine.subsubcontrat211/contract_list := ["contrat_xxx"]; | |
| racine.contrat_xxx/label := "contrat XXX"; | |
| racine.contrat_xxx/price := "xxx"; | |
| `; | |
| let myReader = new Reader(); | |
| let tree = myReader.readFile(contractHieraTexte)['racine']; | |
| console.log(tree); | |
| return tree; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment