SlimRunner

ParseSVGtoDesmos

Jul 21st, 2020
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function parseSvg (source) {
  2.     //Path Tokens
  3.     const PT = Object.defineProperties({}, {
  4.         MOVETO : {
  5.             value: 'm',
  6.             writable: false,
  7.             enumerable: true,
  8.             configurable: true
  9.         },
  10.        
  11.         LINETO : {
  12.             value: 'l',
  13.             writable: false,
  14.             enumerable: true,
  15.             configurable: true
  16.         },
  17.        
  18.         HORZLINE : {
  19.             value: 'h',
  20.             writable: false,
  21.             enumerable: true,
  22.             configurable: true
  23.         },
  24.        
  25.         VERTLINE : {
  26.             value: 'v',
  27.             writable: false,
  28.             enumerable: true,
  29.             configurable: true
  30.         },
  31.        
  32.         CURVETO : {
  33.             value: 'c',
  34.             writable: false,
  35.             enumerable: true,
  36.             configurable: true
  37.         },
  38.        
  39.         SCURVETO : {
  40.             value: 's',
  41.             writable: false,
  42.             enumerable: true,
  43.             configurable: true
  44.         },
  45.        
  46.         QUADTO : {
  47.             value: 'q',
  48.             writable: false,
  49.             enumerable: true,
  50.             configurable: true
  51.         },
  52.        
  53.         SQUADTO : {
  54.             value: 't',
  55.             writable: false,
  56.             enumerable: true,
  57.             configurable: true
  58.         },
  59.        
  60.         ARCTO : {
  61.             value: 'a',
  62.             writable: false,
  63.             enumerable: true,
  64.             configurable: true
  65.         },
  66.        
  67.         CLOSESHAPE : {
  68.             value: 'z',
  69.             writable: false,
  70.             enumerable: true,
  71.             configurable: true
  72.         }
  73.     }); // !TableState defineProperties
  74.    
  75.     let output = '';
  76.     let addFirst = false;
  77.    
  78.     // split path into tokens
  79.     let rxPaths = /[A-Za-z]\s*(?:(?:-?[.0-9]+\s*?,?\s*?)+)?/gm;
  80.     // split tokens into elements
  81.     let rxTokens = /([A-Za-z])(\s*\S+)/m;
  82.     // split parameters into coordinates
  83.     let rxCoords = /(-|(?<=-))?([.0-9]+)/gm;
  84.    
  85.     let tokens = source.match(rxPaths);
  86.    
  87.     let [x, y] = [0, 0];
  88.     let [xs, ys] = [0, 0];
  89.    
  90.     tokens.forEach((token, i) => {
  91.         let tkMatch = token.match(rxTokens);
  92.         let strCurve='';
  93.        
  94.         if (tkMatch !== null) {
  95.             let coords = tkMatch[2].match(rxCoords).map(Number);
  96.            
  97.             switch (tkMatch[1].trim().toLowerCase()) {
  98.                 case PT.MOVETO:
  99.                     addFirst = true;
  100.                     [x, y] = updateTrail(coords, x, y, tkMatch[1] > 'Z');
  101.                     break;
  102.                    
  103.                 case PT.CURVETO:
  104.                     strCurve = getCurveTo(coords, x, y, tkMatch[1] > 'Z');
  105.                     [xs, ys] = updateTrail([coords[2], coords[3]], x, y, tkMatch[1] > 'Z');
  106.                     [x, y] = updateTrail([coords[4], coords[5]], x, y, tkMatch[1] > 'Z');
  107.                     break;
  108.                    
  109.                 case PT.SCURVETO:
  110.                     strCurve = getSmoothCurveTo(coords, x, y, xs, ys, tkMatch[1] > 'Z');
  111.                     [xs, ys] = updateTrail([coords[0], coords[1]], x, y, tkMatch[1] > 'Z');
  112.                     [x, y] = updateTrail([coords[2], coords[3]], x, y, tkMatch[1] > 'Z');
  113.                     break;
  114.                    
  115.                 case PT.LINETO:
  116.                     strCurve = getLineTo(coords, x, y, tkMatch[1] > 'Z');
  117.                     [x, y] = updateTrail(coords, x, y, tkMatch[1] > 'Z');
  118.                     break;
  119.                    
  120.                 case PT.HORZLINE:
  121.                     strCurve = getHVLine(coords[0], x, y, true, tkMatch[1] > 'Z');
  122.                     x = coords[0] + ((tkMatch[1] > 'Z')? x : 0);
  123.                     break;
  124.                
  125.                 case PT.VERTLINE:
  126.                     strCurve = getHVLine(coords[0], x, y, false, tkMatch[1] > 'Z');
  127.                     y = coords[0] + ((tkMatch[1] > 'Z')? y : 0);
  128.                     break;
  129.                    
  130.                 default:
  131.                     throw Error('This path cannot be parsed');
  132.             } // !switch
  133.            
  134.         } else {
  135.             switch (token.trim().toLowerCase()) {
  136.                 case PT.CLOSESHAPE:
  137.                     strCurve = '\\infty,\\infty\n\\infty,\\infty\n';
  138.                     break;
  139.                    
  140.                 default:
  141.                     throw Error('This path cannot be parsed');
  142.             } // !switch
  143.            
  144.         } // if-else
  145.        
  146.         if (addFirst) {
  147.             addFirst = false;
  148.             output += `${x},${y}\n`;
  149.         }
  150.        
  151.         output += strCurve;
  152.        
  153.     });
  154.    
  155.     //copy(output);
  156.    
  157.     let col1 = output.match(/\S+\s*(?=,)/gm);
  158.     let col2 = output.match(/(?<=,)\s*\S+/gm);
  159.    
  160.     // console.log(col1);
  161.     // console.log(col2);
  162.    
  163.     Calc.setExpression({
  164.         type : 'table',
  165.         columns : [{
  166.             latex : 'x',
  167.             values : (col1)
  168.         }, {
  169.             latex : 'y',
  170.             values : (col2)
  171.         }]
  172.     });
  173.    
  174.     function updateTrail(pack, x, y, isRel = false) {
  175.         if (isRel) {
  176.             pack = pack.map((item, i) => {
  177.                 if (i % 2 === 0) {
  178.                     return item + x;
  179.                 } else {
  180.                     return item + y;
  181.                 }
  182.             });
  183.         }
  184.        
  185.         return pack;
  186.     }
  187.    
  188.     function getCurveTo(pack, x, y, isRel = false) {
  189.         if (isRel) {
  190.             pack = pack.map((item, i) => {
  191.                 if (i % 2 === 0) {
  192.                     return item + x;
  193.                 } else {
  194.                     return item + y;
  195.                 }
  196.             });
  197.         }
  198.        
  199.         return `${pack[0]},${pack[1]}\n${pack[2]},${pack[3]}\n${pack[4]},${pack[5]}\n`;
  200.        
  201.     };
  202.    
  203.     function getSmoothCurveTo(pack, x, y, xs, ys, isRel = false) {
  204.         if (isRel) {
  205.             pack = pack.map((item, i) => {
  206.                 if (i % 2 === 0) {
  207.                     return item + x;
  208.                 } else {
  209.                     return item + y;
  210.                 }
  211.             });
  212.         }
  213.        
  214.         return `${2 * x - xs},${2 * y - ys}\n${pack[0]},${pack[1]}\n${pack[2]},${pack[3]}\n`;
  215.        
  216.     };
  217.    
  218.     function getLineTo(pack, x, y, isRel = false) {
  219.         if (isRel) {
  220.             pack = pack.map((item, i) => {
  221.                 if (i % 2 === 0) {
  222.                     return item + x;
  223.                 } else {
  224.                     return item + y;
  225.                 }
  226.             });
  227.         }
  228.        
  229.         return `${(pack[0] + 2 * x) / 3},${(pack[1] + 2 * y) / 3}\n${(2 * pack[0] + x) / 3},${(2 * pack[1] + y) / 3}\n${pack[0]},${pack[1]}\n`;
  230.        
  231.     };
  232.    
  233.     function getHVLine(value, x, y, horz = true, isRel = false) {
  234.         let xy = horz ? x : y;
  235.        
  236.         if (isRel) {
  237.             value += xy;
  238.         }
  239.        
  240.         if (horz) {
  241.             return `${(x + 2 * value) / 3},${y}\n${(2 * x + value) / 3},${y}\n${value},${y}\n`;
  242.         } else {
  243.             return `${x},${(y + 2 * value) / 3}\n${x},${(2 * y + value) / 3}\n${x},${value}\n`;
  244.         }
  245.     }
  246.    
  247. }
Advertisement
Add Comment
Please, Sign In to add comment