src/substituteteacher.js
function _parseSentence(rawSentence) {
    if (!rawSentence || typeof rawSentence !== "string") {
      throw "rawSentence must be a string.";
    }
    var components = [];
    var start, end, endChar;
    for (start = 0, end = 0; end < rawSentence.length; end++) {
      endChar = rawSentence.charAt(end);

      /**
       * Characters that should "detach" from strings are:
       *   ().,/![]*;:{}=?"+ or whitespace
       * Characters that remain that remain a part of the word include:
       *   -#$%^&_`~'
       */
      if (endChar.match(/[\.,"\/!\?\*\+;:{}=()\[\]\s]/g)) {
        // Append the word we've been building
        if (end > start) {
          if (endChar.match(/\s/g)) {
            components.push(rawSentence.slice(start, end) + "&nbsp;");
          } else {
            components.push(rawSentence.slice(start, end));
          }
        }

        // If the character is not whitespace, then it is a special character
        // and should be split off into its own string
        if (!endChar.match(/\s/g)) {
          if (end +1 < rawSentence.length && rawSentence.charAt(end + 1).match(/\s/g)) {
            components.push(endChar + "&nbsp;");
          } else {
            components.push(endChar);
          }
        }

        // The start of the next word is the next character to be seen.
        start = end + 1;
      }
    }
    if (start < end) {
      components.push(rawSentence.slice(start, end));
    }
    return components;
  }
function _parseSentence(rawSentence) {
    if (!rawSentence || typeof rawSentence !== "string") {
      throw "rawSentence must be a string.";
    }
    var components = [];
    var start, end, endChar;
    for (start = 0, end = 0; end < rawSentence.length; end++) {
      endChar = rawSentence.charAt(end);

      /**
       * Characters that should "detach" from strings are:
       *   ().,/![]*;:{}=?"+ or whitespace
       * Characters that remain that remain a part of the word include:
       *   -#$%^&_`~'
       */
      if (endChar.match(/[\.,"\/!\?\*\+;:{}=()\[\]\s]/g)) {
        // Append the word we've been building
        if (end > start) {
          if (endChar.match(/\s/g)) {
            components.push(rawSentence.slice(start, end) + "&nbsp;");
          } else {
            components.push(rawSentence.slice(start, end));
          }
        }

        // If the character is not whitespace, then it is a special character
        // and should be split off into its own string
        if (!endChar.match(/\s/g)) {
          if (end +1 < rawSentence.length && rawSentence.charAt(end + 1).match(/\s/g)) {
            components.push(endChar + "&nbsp;");
          } else {
            components.push(endChar);
          }
        }

        // The start of the next word is the next character to be seen.
        start = end + 1;
      }
    }
    if (start < end) {
      components.push(rawSentence.slice(start, end));
    }
    return components;
  }
function _parseSentence ( rawSentence ) { if ( ! rawSentence || typeof rawSentence !== "string" ) { throw "rawSentence must be a string." ; } var components = [ ] ; var start , end , endChar ; for ( start = 0 , end = 0 ; end < rawSentence . length ; end ++ ) { endChar = rawSentence . charAt ( end ) ; /**
       * Characters that should "detach" from strings are:
       *   ().,/![]*;:{}=?"+ or whitespace
       * Characters that remain that remain a part of the word include:
       *   -#$%^&_`~'
       */ if ( endChar . match ( / [\.,"\/!\?\*\+;:{}=()\[\]\s] / g ) ) { // Append the word we've been building if ( end > start ) { if ( endChar . match ( / \s / g ) ) { components . push ( rawSentence . slice ( start , end ) + "&nbsp;" ) ; } else { components . push ( rawSentence . slice ( start , end ) ) ; } } // If the character is not whitespace, then it is a special character // and should be split off into its own string if ( ! endChar . match ( / \s / g ) ) { if ( end + 1 < rawSentence . length && rawSentence . charAt ( end + 1 ) . match ( / \s / g ) ) { components . push ( endChar + "&nbsp;" ) ; } else { components . push ( endChar ) ; } } // The start of the next word is the next character to be seen. start = end + 1 ; } } if ( start < end ) { components . push ( rawSentence . slice ( start , end ) ) ; } return components ; }
Parse the raw sentence into an array of words.

Separate the sentence by spaces, and then go along each word and pull
punctuation off words that end with a punctuation symbol:

"We're here (in Wilkes-Barre), finally!" =>
["We're", "here", "(", "in", "Wilkes-Barre", ")", ",", "finally", "!"]

TODO: figure out some way to annotate puncatation so that it can be
rendered without a space in it.

@param {string[]} rawSentences the sentences to parse
@returns {string[][]} sentences the sentences split up into tokens
Parse the raw sentence into an array of words .