/***************************************************************************** ** Common tagulous functionality *****************************************************************************/ var Tagulous = (function () { /************************************************************************** ** Port of utils.py */ // Constants to improve legibility var COMMA = ',', SPACE = ' ', QUOTE = '"' ; function escapeQuotes(count) { return Array(Math.floor(count / 2) + 1).join(QUOTE); } function parseTags(str, spaceDelimiter, withRaw) { /** Parse a tag string Returns a sorted list of unique tags If spaceDelimiter is false, only commas will be used as the tag name delimiter. If it is unset, it will default to true; when true, spaces are used as well as commas. If withRaw == true, returns a tuple of two lists: tags List of tags, unsorted and not unique raws List of raw strings after parsed tag If the last tag is not explicitly ended with a delimiter, the corresponding item in ``raws `` will be ``null`` to indicate that the parser unexpectedly ran out of characters. This can help with parsing live input; if the last item in ``raw`` is an empty string the tag has been closed; if it is ``null`` then the tag is still being written. */ // Empty string is easy if (!str) { if (withRaw) { return [[],[]]; } return []; } // Prep vars for parser var tags = [], raws = [], tag = '', delimiter = SPACE, strLen = str.length, strLast = strLen - 1, index, inQuote, chr, tagLen, leftCount, rightCount ; // Disable spaces if (spaceDelimiter === false) { delimiter = COMMA; } // Loop through chars for (index=0; index -1 || str.indexOf(SPACE) > -1) { safe.push(QUOTE + str + QUOTE); } else { safe.push(str); } } safe.sort(); return safe.join(', '); } return { parseTags: parseTags, renderTags: renderTags }; })();