180:                // This is done to match parseArray() behavior.
220:    return {
247:        return {
264:        return label;
280:        return label;
291:        return {
305:        return parent;
308:        return new MathNode("mrow",
            // Remove the empty cell that was placed at the beginning of `row`.
            row.shift();
        }
        row = [];
        body.push(row);
    }

    // End row group
    parser.gullet.endGroup();
    // End array group defining \\
    parser.gullet.endGroup();

    // define column separation.
    const cols = new Array(body[0].length).fill({
        type: "align",
        align: "c",
        pregap: 0.25,  // CD package sets \enskip between columns.
        postgap: 0.25, // So pre and post each get half an \enskip, i.e. 0.25em.
    });

    return {
        type: "array",
        mode: "math",
        body,
        arraystretch: 1,
        addJot: true,
        rowGaps: [null],
        cols,
        colSeparationType: "CD",
        hLinesBeforeRow: new Array(body.length + 1).fill([]),
    };
}

// The functions below are not available for general use.
// They are here only for internal use by the {CD} environment in placing labels
// next to vertical arrows.

// We don't need any such functions for horizontal arrows because we can reuse
// the functionality that already exists for extensible arrows.

defineFunction({
