Fork me on GitHub

editor/editor-mathpath.js

            
            /**
 * @module editor/mathpath
 * @private
 */
define([], 
    function() {



/**
 * 
 * @memberof module:editor/mathpath
 * @param {Object} path 
 * @param {number} extent
 * @return {string}
 * @private
 */
function pathToString(path, extent) {
    let result = '';
    for (const segment of path) {
        result += segment.relation + ':' + segment.offset + '/';
    }
    if (extent) {
        result += '#' + extent;
    }
    return result;
}


/**
 * 
 * @memberof module:editor/mathpath
 * @param {string} string 
 * @return {Object}
 * @private
 */
function pathFromString(string) {
    // Reset the path
    const result = {path: [], extent: 0};

    // Parse the selection extent, if present
    const components = string.split('#');
    if (components.length > 1) {
        result.extent = parseInt(components[1]);
    }

    // Parse the segments
    const segments = components[0].split('/');
    for (const segment of segments) {
        const m2 = segment.match(/([^:]*):(.*)/);
        if (m2) {
            result.path.push({
                relation: m2[1],
                offset: parseInt(m2[2])
            });
        }
    }

    return result;
}

/**
 * Given two paths, return a path representing their common ancestor.
 * 
 * @param {Array.<string>} p 
 * @param {Array.<string>} q 
 * @return {Array.<string>}
 * @memberof module:editor/mathpath
 * @private
 */
function pathCommonAncestor(p, q) {
    const result = [];
    const maxIndex = Math.min(p.length - 1, q.length - 1);
    let i = 0;
    while ( i <= maxIndex && 
            p[i].relation === q[i].relation && 
            p[i].offset === q[i].offset) {
        result.push(p[i]);
        i += 1;
    }
    return result;
}

/**
 * 
 * @param {Array.<string>} p 
 * @param {Array.<string>} q 
 * @return {number} 0 if the paths are identical
 *  - 1 if they are siblings
 *  - >1 if they are not siblings
 * @memberof module:editor/mathpath
 * @private
 */
function pathDistance(p, q) {
     let result = 0;
     let i = -1;
     let done = false;
     while (!done) {
        i += 1;
        done = i >= p.length || i >= q.length;
        done = done || 
            !(p[i].relation === q[i].relation && 
            p[i].offset === q[i].offset);
     }
    if (i === p.length && i === q.length) {
        // They're identical
        result = 0;     
    } else if (i + 1 === p.length && i + 1 === q.length &&
        p[i].relation === q[i].relation ) {
        // They're siblings
        result = 1;
    } else {
        result = 2;
    }

     return result;
}



function clone(path) {
    return pathFromString(pathToString(path)).path;
}

return {
    pathFromString,
    pathToString,
    pathDistance,
    pathCommonAncestor,
    clone

}


})