src/papercut.js
/**
	 * papercut generates the union of each group of characters in an svg DOM element
	 * @param {Object} domElem - svg element generated from Bowlcut.
	 * @returns {Object} New svg DOM element with unions applied.
	 */
papercut generates the union of each group of characters in an svg DOM element
@param {Object} domElem - svg element generated from Bowlcut.
@returns {Object} New svg DOM element with unions applied.
papercut generates the union of each group of characters in an svg DOM element @param { Object } domElem - svg element generated from Bowlcut . @returns { Object } New svg DOM element with unions applied .
function papercut(domElem) {
  let pathArrays = [];
  domElem.childNodes.forEach(function getSeparatePaths(compoundPath) {
    if (compoundPath.tagName !== 'path') {
      return;
    }
    pathArrays.push([]);
    let charPaths = compoundPath.getAttribute('d') || '';
    let charFill = compoundPath.getAttribute('fill') || '';
    let charStroke = compoundPath.getAttribute('stroke') || '';
    let charStrokeWidth = compoundPath.getAttribute('stroke-width') || '';
    let charStrokeLinejoin = compoundPath.getAttribute('stroke-linejoin') || '';
    let charStrokeLinecap = compoundPath.getAttribute('stroke-linecap') || '';
    charPaths = charPaths.split('Z');
    charPaths.forEach(function stylePaths(path) {
      if (path.length > 0) {
        path = path.concat('Z');
        let tempPath = createSVGElement('path');
        tempPath.setAttribute('d', path);
        tempPath.setAttribute('fill', charFill);
        tempPath.setAttribute('stroke', charStroke);
        tempPath.setAttribute('stroke-width', charStrokeWidth);
        tempPath.setAttribute('stroke-linejoin', charStrokeLinejoin);
        tempPath.setAttribute('stroke-linecap', charStrokeLinecap);
        pathArrays[pathArrays.length - 1].push(tempPath);
      }
    });
  });
  let wordGroups = [];
  pathArrays.forEach(function traverseWord(word) {
    let characters = [];
    word.forEach(function putWordsToPaper(character, i) {
      characters[i] = paper.project.importSVG(character);
    });
    if (characters.length > 1) {
      let newPaths = new Array(characters.length - 1);
      newPaths[newPaths.length - 1] = characters[characters.length - 2].unite(characters[characters.length - 1]);
      for (let i = newPaths.length - 1; i > 0; i--) {
        newPaths[i - 1] = newPaths[i].unite(characters[i - 1]);
      }
      characters[characters.length - 1].remove();
      for (let i = newPaths.length - 1; i > 0; i--) {
        newPaths[i].remove();
        characters[i].remove();
      }
      characters[0].remove();
    }
    wordGroups.push(paper.project.exportSVG({precision: 3}));
    paper.project.clear();
  });
  let wordGroup = createSVGElement('g');
  for (let i = 0; i < wordGroups.length; i++) {
    wordGroup.appendChild(wordGroups[i].firstChild);
  }
  return wordGroup;
}
function papercut ( domElem ) { let pathArrays = [ ] ; domElem . childNodes . forEach ( function getSeparatePaths ( compoundPath ) { if ( compoundPath . tagName !== 'path' ) { return ; } pathArrays . push ( [ ] ) ; let charPaths = compoundPath . getAttribute ( 'd' ) || '' ; let charFill = compoundPath . getAttribute ( 'fill' ) || '' ; let charStroke = compoundPath . getAttribute ( 'stroke' ) || '' ; let charStrokeWidth = compoundPath . getAttribute ( 'stroke-width' ) || '' ; let charStrokeLinejoin = compoundPath . getAttribute ( 'stroke-linejoin' ) || '' ; let charStrokeLinecap = compoundPath . getAttribute ( 'stroke-linecap' ) || '' ; charPaths = charPaths . split ( 'Z' ) ; charPaths . forEach ( function stylePaths ( path ) { if ( path . length > 0 ) { path = path . concat ( 'Z' ) ; let tempPath = createSVGElement ( 'path' ) ; tempPath . setAttribute ( 'd' , path ) ; tempPath . setAttribute ( 'fill' , charFill ) ; tempPath . setAttribute ( 'stroke' , charStroke ) ; tempPath . setAttribute ( 'stroke-width' , charStrokeWidth ) ; tempPath . setAttribute ( 'stroke-linejoin' , charStrokeLinejoin ) ; tempPath . setAttribute ( 'stroke-linecap' , charStrokeLinecap ) ; pathArrays [ pathArrays . length - 1 ] . push ( tempPath ) ; } } ) ; } ) ; let wordGroups = [ ] ; pathArrays . forEach ( function traverseWord ( word ) { let characters = [ ] ; word . forEach ( function putWordsToPaper ( character , i ) { characters [ i ] = paper . project . importSVG ( character ) ; } ) ; if ( characters . length > 1 ) { let newPaths = new Array ( characters . length - 1 ) ; newPaths [ newPaths . length - 1 ] = characters [ characters . length - 2 ] . unite ( characters [ characters . length - 1 ] ) ; for ( let i = newPaths . length - 1 ; i > 0 ; i -- ) { newPaths [ i - 1 ] = newPaths [ i ] . unite ( characters [ i - 1 ] ) ; } characters [ characters . length - 1 ] . remove ( ) ; for ( let i = newPaths . length - 1 ; i > 0 ; i -- ) { newPaths [ i ] . remove ( ) ; characters [ i ] . remove ( ) ; } characters [ 0 ] . remove ( ) ; } wordGroups . push ( paper . project . exportSVG ( { precision : 3 } ) ) ; paper . project . clear ( ) ; } ) ; let wordGroup = createSVGElement ( 'g' ) ; for ( let i = 0 ; i < wordGroups . length ; i ++ ) { wordGroup . appendChild ( wordGroups [ i ] . firstChild ) ; } return wordGroup ; }
papercut generates the union of each group of characters in an svg DOM element
 @param {Object} domElem - svg element generated from Bowlcut.
papercut generates the union of each group of characters in an svg DOM element @param { Object } domElem - svg element generated from Bowlcut .
// parse the svg DOM element into separate path elements // use paper.js to do the thing // import each character into paper.js but keep track of them // create a new array for union paths // unite the last two characters and keep track of it in the new array // do all of the unions and keep track of them in the new array // characters is one element longer than the new array so remove // the last path from the paper project so it isn't exported // remove all paths from both arrays EXCEPT for the first // we only care about the first element of the new array because it // has a path representing the union of all of the characters... so // kill the last remaining artifact: the first character // now that we only have one path left, the path representing all // unioned characters, export the contents of the project // clear the project so subsequent uses of Papercut don't contain // paths from the previous union event // create a container for the new paths and append them