function kap(text, measureText, measure, hyphenation) {
  console.log("Typesetting hyphenated text:", text, measure);
  if (!hyphenation) {
    text = text.replace(/\|/g, '');
  }

  let hyphenWidth = measureText('-');
  let spaceWidth = measureText('\u00A0');
  let nodes = [];

  text.split(/([.,:;!?] |\s|\||<.*?>)/u).forEach(function (fragment) {
    let fragmentWidth = measureText(fragment);

    if (fragment === ' ') {
      let stretch = (spaceWidth * 3)  / 6;
      let shrink = (spaceWidth * 3) / 9;

      nodes.push(linebreak.glue(spaceWidth, stretch, shrink));
    } else if (fragment === '|') {
      // nodes.push(linebreak.penalty(hyphenWidth, 100, 1));
      nodes.push(linebreak.penalty(hyphenWidth * 0.25, 100, 1));
    } else if (fragment.match(/(<.*?>)/u)) {
      nodes.push(linebreak.tag(fragmentWidth, fragment));
    } else if (fragment.match(/[.,:;!?] /u)) {
      let punctuation = fragment.match(/([.,:;!?])( )/u);
      let punctuationSymbolWidth = measureText(punctuation[1]) * 0.25;
      let punctuationWidth = measureText(punctuation[1]) * 0.75 + spaceWidth;
      nodes.push(linebreak.box(punctuationSymbolWidth, punctuation[1]));
      let stretch = (punctuationWidth * 3)  / 6;
      let shrink = (punctuationWidth * 3) / 9;

      nodes.push(linebreak.glue(punctuationWidth, stretch, shrink));
    } else if (fragment.match(/(\s+)/u)) {

    } else {
      nodes.push(linebreak.box(fragmentWidth, fragment));
    }
  });

  nodes.push(linebreak.glue(0, linebreak.infinity, 0));
  nodes.push(linebreak.penalty(0, -linebreak.infinity, 1));

  let demerits = {
    line: 10,
    flagged: 100,
    fitness: 3000
  };

  let breaks = linebreak(nodes, measure, { tolerance: 3, demerits });

  if (!breaks.length) {
    breaks = linebreak(nodes, measure, { tolerance: 10, demerits });
  }

  return { nodes, breaks };
}
