1 /* 2 * CodePointSource.js - Source of code points from a string 3 * 4 * Copyright © 2013-2015, 2018, JEDLSoft 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 var isPunct = require("./isPunct.js"); 21 var NormString = require("./NormString.js"); 22 23 /** 24 * @class 25 * Represents a buffered source of code points. The input string is first 26 * normalized so that combining characters come out in a standardized order. 27 * If the "ignorePunctuation" flag is turned on, then punctuation 28 * characters are skipped. 29 * 30 * @constructor 31 * @private 32 * @param {NormString|string} str a string to get code points from 33 * @param {boolean} ignorePunctuation whether or not to ignore punctuation 34 * characters 35 */ 36 var CodePointSource = function(str, ignorePunctuation) { 37 this.chars = []; 38 // first convert the string to a normalized sequence of characters 39 var s = (typeof(str) === "string") ? new NormString(str) : str; 40 this.it = s.charIterator(); 41 this.ignorePunctuation = typeof(ignorePunctuation) === "boolean" && ignorePunctuation; 42 }; 43 44 /** 45 * Return the first num code points in the source without advancing the 46 * source pointer. If there are not enough code points left in the 47 * string to satisfy the request, this method will return undefined. 48 * 49 * @param {number} num the number of characters to peek ahead 50 * @return {string|undefined} a string formed out of up to num code points from 51 * the start of the string, or undefined if there are not enough character left 52 * in the source to complete the request 53 */ 54 CodePointSource.prototype.peek = function(num) { 55 if (num < 1) { 56 return undefined; 57 } 58 if (this.chars.length < num && this.it.hasNext()) { 59 for (var i = 0; this.chars.length < 4 && this.it.hasNext(); i++) { 60 var c = this.it.next(); 61 if (c && !this.ignorePunctuation || !isPunct(c)) { 62 this.chars.push(c); 63 } 64 } 65 } 66 if (this.chars.length < num) { 67 return undefined; 68 } 69 return this.chars.slice(0, num).join(""); 70 }; 71 /** 72 * Advance the source pointer by the given number of code points. 73 * @param {number} num number of code points to advance 74 */ 75 CodePointSource.prototype.consume = function(num) { 76 if (num > 0) { 77 this.peek(num); // for the iterator to go forward if needed 78 if (num < this.chars.length) { 79 this.chars = this.chars.slice(num); 80 } else { 81 this.chars = []; 82 } 83 } 84 }; 85 86 module.exports = CodePointSource; 87