makeVList = function(children, positionType, positionData, options) {
                    var depth;
                    var currPos;
                    var i;
                    if (positionType === "individualShift") {
                        var oldChildren = children;
                        children = [oldChildren[0]];

                        // Add in kerns to the list of children to get each element to be
                        // shifted to the correct specified shift
                        depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
                        currPos = depth;
                        for (i = 1; i < oldChildren.length; i++) {
                            var diff = -oldChildren[i].shift - currPos -
                                oldChildren[i].elem.depth;
                            var size = diff -
                                (oldChildren[i - 1].elem.height +
                                    oldChildren[i - 1].elem.depth);

                            currPos = currPos + diff;

                            children.push({type: "kern", size: size});
                            children.push(oldChildren[i]);
                        }
                    } else if (positionType === "top") {
                        // We always start at the bottom, so calculate the bottom by adding up
                        // all the sizes
                        var bottom = positionData;
                        for (i = 0; i < children.length; i++) {
                            if (children[i].type === "kern") {
                                bottom -= children[i].size;
                            } else {
                                bottom -= children[i].elem.height + children[i].elem.depth;
                            }
                        }
                        depth = bottom;
                    } else if (positionType === "bottom") {
                        depth = -positionData;
                    } else if (positionType === "shift") {
                        depth = -children[0].elem.depth - positionData;
                    } else if (positionType === "firstBaseline") {
                        depth = -children[0].elem.depth;
                    } else {
                        depth = 0;
                    }

                    // Make the fontSizer
                    var maxFontSize = 0;
                    for (i = 0; i < children.length; i++) {
                        if (children[i].type === "elem") {
                            maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize);
                        }
                    }
                    var fontSizer = makeFontSizer(options, maxFontSize);

                    // Create a new list of actual children at the correct offsets
                    var realChildren = [];
                    currPos = depth;
                    for (i = 0; i < children.length; i++) {
                        if (children[i].type === "kern") {
                            currPos += children[i].size;
                        } else {
                            var child = children[i].elem;

                            var shift = -child.depth - currPos;
                            currPos += child.height + child.depth;

                            var childWrap = makeSpan([], [fontSizer, child]);
                            childWrap.height -= shift;
                            childWrap.depth += shift;
                            childWrap.style.top = shift + "em";

                            realChildren.push(childWrap);
                        }
                    }

                    // Add in an element at the end with no offset to fix the calculation of
                    // baselines in some browsers (namely IE, sometimes safari)
                    var baselineFix = makeSpan(
                        ["baseline-fix"], [fontSizer, new domTree.symbolNode("\u200b")]);
                    realChildren.push(baselineFix);

                    var vlist = makeSpan(["vlist"], realChildren);
                    // Fix the final height and depth, in case there were kerns at the ends
                    // since the makeSpan calculation won't take that in to account.
                    vlist.height = Math.max(currPos, vlist.height);
                    vlist.depth = Math.max(-depth, vlist.depth);
                    return vlist;
                }
Create an HTML className based on a list of classes. In addition to joining
with spaces, we also remove null or empty classes.