>} lines - lines to be formatted
@returns {Element} html element containing the glosses
*/
Leipzig.prototype.format = function format(groups, wrapperType, lineNumStart) {
var _this = this;
var tag = this.tag;
var spacing = this.spacing;
var autoTag = this.autoTag;
var classes = this.classes;
var wrapper = document.createElement(wrapperType);
var innerHtml = [];
addClass(wrapper, classes.words);
groups.forEach(function (group) {
var groupLines = [];
var isEmpty = true;
group.forEach(function (line, lineNumOffset) {
var lineNum = lineNumStart + lineNumOffset;
var lineClasses = [classes.line, classes.lineNum + lineNum];
if (line.length) {
isEmpty = false;
}
if (lineNumOffset > 0 && autoTag) {
line = _this.tag(line);
}
groupLines.push('' + line + '
');
});
var wordClasses = classes.word;
if (isEmpty && !spacing) {
wordClasses += ' ' + classes.spacer;
}
innerHtml.push('', groupLines.join(''), '
');
});
wrapper.innerHTML = innerHtml.join('');
return wrapper;
};
/**
Runs the glosser
*/
Leipzig.prototype.gloss = function gloss(callback) {
var _this2 = this;
var selector = this.selector;
var classes = this.classes;
var events = this.events;
var firstLineOrig = this.firstLineOrig;
var lastLineFree = this.lastLineFree;
var spacing = this.spacing;
var async = this.async;
/** Processes an individual gloss element */
var processGloss = function processGloss(gloss, callback) {
if (!(gloss instanceof Element)) {
var err = new Error('Invalid gloss element');
if (typeof callback === 'function') {
callback(err);
} else {
throw err;
}
}
var lines = Array.prototype.slice.call(gloss.children);
var linesToAlign = [];
var firstRawLine = null;
var firstRawLineNum = 0;
triggerEvent(gloss, events.beforeGloss);
if (firstLineOrig) {
var firstLine = lines[0];
addClass(firstLine, classes.original);
}
if (lastLineFree) {
var lastLine = lines[lines.length - 1];
addClass(lastLine, classes.freeTranslation);
}
// process each line in the gloss
lines.forEach(function (line, lineNum) {
// don't align lines that are free translations or original,
// unformatted lines
var isOrig = hasClass(line, classes.original);
var isFree = hasClass(line, classes.freeTranslation);
var shouldSkip = hasClass(line, classes.noAlign);
var shouldAlign = !isOrig && !isFree && !shouldSkip;
if (shouldAlign) {
triggerEvent(line, events.beforeLex, { lineNum: lineNum });
var tokens = _this2.lex(line.innerHTML);
triggerEvent(line, events.afterLex, {
tokens: tokens,
lineNum: lineNum
});
linesToAlign.push(tokens);
addClass(line, classes.hidden);
// if this is the first aligned line, mark the location
// so that the final aligned glosses can be inserted here
if (!firstRawLine) {
firstRawLine = line;
firstRawLineNum = lineNum;
}
} else {
addClass(line, classes.line);
addClass(line, classes.lineNum + lineNum);
}
});
var lastRawLineNum = firstRawLineNum + (linesToAlign.length - 1);
triggerEvent(gloss, events.beforeAlign, {
lines: linesToAlign,
firstLineNum: firstRawLineNum,
lastLineNum: lastRawLineNum
});
var alignedLines = _this2.align(linesToAlign);
triggerEvent(gloss, events.afterAlign, {
lines: alignedLines,
firstLineNum: firstRawLineNum,
lastLineNum: lastRawLineNum
});
// determine which type of element the aligned glosses should be wrapped in
var alignedWrapper = undefined;
if (gloss.tagName === 'UL' || gloss.tagName === 'OL') {
alignedWrapper = 'li';
} else {
alignedWrapper = 'div';
}
triggerEvent(gloss, events.beforeFormat, {
lines: alignedLines,
firstLineNum: firstRawLineNum,
lastLineNum: lastRawLineNum
});
var formattedLines = _this2.format(alignedLines, alignedWrapper, firstRawLineNum);
gloss.insertBefore(formattedLines, firstRawLine);
triggerEvent(formattedLines, events.afterFormat, {
firstLineNum: firstRawLineNum,
lastLineNum: lastRawLineNum
});
// finish up by adding relevant classes to the main container
if (!spacing) {
addClass(gloss, classes.noSpace);
}
addClass(gloss, classes.glossed);
triggerEvent(gloss, events.afterGloss);
};
var glossElements = undefined;
if (selector instanceof NodeList) {
glossElements = selector;
} else if (typeof selector === 'string') {
glossElements = document.querySelectorAll(selector);
} else if (selector instanceof Element) {
// create an array so we can loop later on
glossElements = [selector];
} else {
var err = new Error('Invalid selector');
if (typeof callback === 'function') {
callback(err);
} else {
throw err;
}
}
triggerEvent(document, events.start, { glosses: glossElements });
// process each gloss
var glosses = Array.prototype.slice.call(glossElements);
var _loop = function (i) {
var gloss = glosses[i];
if (async) {
window.setTimeout(function () {
return processGloss(gloss, callback);
});
} else {
processGloss(gloss, callback);
}
};
for (var i = 0; i < glosses.length; i++) {
_loop(i);
}
window.setTimeout(function () {
if (typeof callback === 'function') {
callback(null, glossElements);
}
triggerEvent(document, events.complete, { glosses: glossElements });
});
};
module.exports = Leipzig;
});