Prevent spaces at the end of single flag rend attributes

function InitTextHandlers() {
    // QUESTION: We could also take an argument and throw all text handlers from
    // extensions into the same dictionary

    Self._property:TextHandlers = CreateDictionary(
        'text.staff.expression', 'ExpressionTextHandler',
        'text.system.page_aligned.title', 'PageTitleHandler',
        'text.system.page_aligned.subtitle', 'PageTitleHandler',
        'text.system.page_aligned.composer', 'PageComposerTextHandler',
        'text.system.tempo', 'TempoTextHandler',
        'text.staff.space.figuredbass', 'FiguredBassTextHandler'
    );

    Self._property:TextSubstituteMap = CreateDictionary(
        'Title', CreateSparseArray('Title'),
        'Subtitle', CreateSparseArray('Title', CreateDictionary('type', 'subordinate')),
        'Dedication', CreateSparseArray('Dedication'),
        // <composer>, <arranger>, <lyricist>, <userRestrict> and <publisher>
        // are only allowed in a few places, e.g. metadata or title pages.
        // We therfore use more generic elements
        'Composer', CreateSparseArray('PersName', CreateDictionary('role', 'Composer')),
        'Arranger', CreateSparseArray('PersName', CreateDictionary('role', 'Arranger')),
        'Lyricist', CreateSparseArray('PersName', CreateDictionary('role', 'Lyricist')),
        'Artist', CreateSparseArray('PersName', CreateDictionary('role', 'Artist')),
        // <useRestrict> is only allowed on <titlePage>, so use generic element
        'Copyright', CreateSparseArray('Seg', CreateDictionary('type', 'Copyright')),
        // <publisher> is only allowed in a few places, so use generic element
        // We don't even know if it's a person or an institution
        'Publisher', CreateSparseArray('Seg', CreateDictionary('type', 'Publisher')),
        'MoreInfo', CreateSparseArray('Seg', CreateDictionary('type', 'MoreInfo')),
        'PartName', CreateSparseArray('Seg', CreateDictionary('type', 'PartName'))
    );
}  //$end

function HandleText (textObject) {
    // TODO: Move InitTextHandlers() call to a global initialization function
    InitTextHandlers();
    if (null != Self._property:Extension and null != Extension.TextHandlers)
    {
        // TODO: We need to check for both StyleId *and* StyleAsText so we can
        // handle custom styles
        textHandler = Extension.TextHandlers[textObject.StyleId];
        if (null != textHandler)
        {
            return Extension.@textHandler(textObject);
        }
    }

    textHandler = TextHandlers[textObject.StyleId];
    if (null != textHandler)
    {
        return @textHandler(textObject);
    }
}  //$end

function ExpressionTextHandler (textObject) {
    dynam = AddBarObjectInfoToElement(textObject, libmei.Dynam());
    AddFormattedText(dynam, textObject);
    return dynam;
}  //$end

function PageTitleHandler (textObject) {
    anchoredText = libmei.AnchoredText();
    title = libmei.Title();
    if (textObject.StyleId = 'text.system.page_aligned.subtitle')
    {
        libmei.AddAttribute(title, 'type', 'subordinate');
    }

    libmei.AddChild(anchoredText, title);
    AddFormattedText(title, textObject);

    return anchoredText;
}  //$end

function PageComposerTextHandler (textObject) {
    // 'text.system.page_aligned.composer'
    return AddBarObjectInfoToElement(textObject, CreateAnchoredText(textObject));
}  //$end

function TempoTextHandler (textObject) {
    // 'text.system.tempo'
    tempo = libmei.Tempo();
    libmei.AddChild(tempo, CreateAnchoredText(textObject));
    return tempo;
}  //$end

function FiguredBassTextHandler (textObject) {
    // 'text.staff.space.figuredbass'
    harm = AddBarObjectInfoToElement(textObject, libmei.Harm());
    fb = libmei.Fb();
    libmei.AddChild(harm, fb);
    ConvertFbFigures(fb, textObject);
    return harm;
}  //$end

function CreateAnchoredText (textObj) {
    //$module(ExportConverters.mss)
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObj);
    return anchoredText;
}  //$end

function AddFormattedText (parentElement, textObj) {
    textWithFormatting = textObj.TextWithFormatting;
    if (textWithFormatting.NumChildren < 2 and CharAt(textWithFormatting[0], 0) != '\\')
    {
        libmei.SetText(parentElement, textObj.Text);
        return null;
    }

    nodes = CreateSparseArray();

    state = CreateDictionary(
        'currentText', null,
        'rendAttributes', CreateDictionary(),
        'rendFlags', CreateDictionary(),
        // TODO: Also track the active character style (mainly
        // `\ctext.character.musictext\`, and custom styles)
        'nodes', nodes,
        'paragraphs', null
    );

    for each component in textObj.TextWithFormatting
    {
        switch (Substring(component, 0, 2))
        {
            case ('\\n')
            {
                PushStyledText(state);
                nodes.Push(libmei.Lb());
            }
            case ('\\N')
            {
                PushStyledText(state);
                // TODO: Add <p> if it is allowed within parentElement (use libmei.GetName())
                nodes.Push(libmei.Lb());
            }
            case ('\\B')
            {
                SwitchTextStyle(state, 'fontweight', 'bold');
            }
            case ('\\b')
            {
                SwitchTextStyle(state, 'fontweight', 'normal');
            }
            case ('\\I')
            {
                SwitchTextStyle(state, 'fontstyle', 'italic');
            }
            case ('\\i')
            {
                SwitchTextStyle(state, 'fontstyle', 'normal');
            }
            case ('\\U')
            {
                SwitchTextStyle(state, 'rend', 'underline', true);
            }
            case ('\\u')
            {
                SwitchTextStyle(state, 'rend', 'underline', false);
            }
            case ('\\f')
            {
                SwitchFont(state, GetTextCommandArg(component));
            }
            case ('\\c')
            {
                // TODO: Can we sensibly handle a character style change? The
                // only built-in one seem to be `text.character.musictext`. We
                // might want to allow Extensions to handle custom character
                // styles.
                ;
            }
            case ('\\s')
            {
                fontsize = ConvertOffsetsToMEI(GetTextCommandArg(component));
                SwitchTextStyle(state, 'fontsize', fontsize);
            }
            case ('\\v')
            {
                // Vertical scale change (vertical stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\h')
            {
                // Horizontal scale change (horizontal stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\t')
            {
                // Tracking. Probably not possible to handle.
                ;
            }
            case ('\\p')
            {
                SwitchBaselineAdjust(state, GetTextCommandArg(component));
            }
            case ('\\$') {
                AppendTextSubstitute(state, GetTextCommandArg(component));
            }
            case ('\\\\')
            {
                // According to the documentation, 'backslashes themselves are
                // represented by \\ , to avoid conflicting with the above
                // commands'. Though that does not seem to work, let's just
                // assume it does in case Avid fixes this.

                // We strip one leading backspace.
                state.currentText = state.currentText & Substring(component, 1);
            }
            default
            {
                // This is regular text
                state.currentText = state.currentText & component;
            }
        }
    }

    PushStyledText(state);

    nodeCount = nodes.Length;
    precedingElement = null;

    nodeIndex = 0;
    while (nodeIndex < nodeCount)
    {
        node = nodes[nodeIndex];
        if (IsObject(node))
        {
            // We have an element
            libmei.AddChild(parentElement, node);
            precedingElement = node;
        }
        else
        {
            // We have a text node
            text = node;
            // If there are multiple adjacent text nodes, we need to join them
            while (nodeIndex < nodeCount and not IsObject(nodes[nodeIndex + 1])) {
                nodeIndex = nodeIndex + 1;
                text = text & nodes[nodeIndex];
            }

            if (precedingElement = null)
            {
                libmei.SetText(parentElement, text);
            }
            else
            {
                libmei.SetTail(precedingElement, text);
            }
        }
        nodeIndex = nodeIndex + 1;
    }
}  //$end

function NewTextParagraph (state) {
    // TODO!
    ;
}  //$end

function GetTextCommandArg (command) {
    // Remove leading part, e.g. the '\$' or '\s' and trailing '\'
    return Substring(command, 2, Length(command) - 3);
}  //$end

function SwitchBaselineAdjust (state, param) {
    sup = (param = 'superscript');
    sub = (param = 'subscript');
    if (sup != state.rendFlags['sup'] or sub != state.rendFlags['sub']) {
        // Style changed, push the previous text before changing the style
        PushStyledText(state);
    }
    state.rendFlags['sup'] = sup;
    state.rendFlags['sub'] = sub;
}  //$end

function ResetTextStyles (state, infoOnly) {
    // If `infoOnly` is `true`, does not make any changes, only tells us if
    // there are re-settable styles
    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            if (infoOnly and state.rendAttributes[attName] != null)
            {
                return true;
            }
            state.rendAttributes[attName] = null;
        }
    }

    if (null != state.rendFlags)
    {
        for each Name flagName in state.rendFlags
        {
            if (infoOnly and state.rendFlags[flagName])
            {
                return true;
            }
            state.rendFlags[flagName] = false;
        }
    }
    return false;
}  //$end

function SwitchFont (state, fontName) {
    if (fontName = '_')
    {
        // Before resetting the style, we have to add text preceding the '\f_\'
        // style reset – but only if the style reset actually changes something.
        if (ResetTextStyles(state, true))
        {
            PushStyledText(state);
            ResetTextStyles(state, false);
        }
    }
    else
    {
        SwitchTextStyle(state, 'fontfam', fontName);
    }
}  //$end

function SwitchTextStyle (state, attName, value) {
    if (state.rendAttributes[attName] != value)
    {
        // Style changes, so append current text before modifying style state
        PushStyledText(state);
    }
    state.rendAttributes[attName] = value;
}  //$end

function SwitchRendFlags (state, flagName, value) {
    if (state.rendFlags[flagName] != value)
    {
        PushStyledText(state);
    }
    state.rendFlags[flagName] = value;
}  //$end

function PushStyledText (state) {
    if (state.currentText = '')
    {
        return null;
    }

    styleAttributes = GetStyleAttributes(state);
    if (null = styleAttributes)
    {
        // We attach unstyled text without wrapping it in <rend>
        state.nodes.Push(state.currentText);
    }
    else
    {
        rend = libmei.Rend();
        for each Name attName in styleAttributes {
            libmei.AddAttribute(rend, attName, styleAttributes[attName]);
        }
        libmei.SetText(rend, state.currentText);
        state.nodes.Push(rend);
    }

    state.currentText = '';
}  //$end

function GetStyleAttributes (state) {
    rendAttributes = null;

    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            value = state.rendAttributes[attName];
            if (null != value)
            {
                if (null = rendAttributes) {
                    rendAttributes = CreateDictionary();
                }
                rendAttributes[attName] = value;
            }
        }
    }

    if (null != state.rendFlags)
    {
        rendAttValue = '';
        firstRendFlag = true;
        for each Name flagName in state.rendFlags
        {
            flagActive = state.rendFlags[flagName];
            if (flagActive)
            {
                if (firstRendFlag = true)
                {
                    rendAttValue = rendAttValue & flagName;
                    firstRendFlag = false;
                }
                else
                {
                    rendAttValue = rendAttValue & ' ' & flagName;
                }
            }
        }
        if (rendAttValue != '')
        {
            if (null = rendAttributes) {
                rendAttributes = CreateDictionary();
            }
            rendAttributes['rend'] = rendAttValue;
        }
    }

    return rendAttributes;
}  //$end

function AppendTextSubstitute (state, substituteName) {
    score = Self._property:ActiveScore;

    textSubstituteInfo = TextSubstituteMap[substituteName];
    if (null = textSubstituteInfo)
    {
        // No known substitution. Sibelius renders those literally.
        state.currentText = state.currentText & '\\$' & substituteName & '\\';
        return null;
    }

    substitutedText = score.@substituteName;
    if (substitutedText = '') {
        // TODO: Also check for all-whitespace text
        return null;
    }

    element = DataToMEI(textSubstituteInfo);
    state.nodes.Push(element);

    styleAttributes = GetStyleAttributes(state);
    rendElement = null;
    if (null = styleAttributes)
    {
        libmei.SetText(element, substitutedText);
    }
    else
    {
        rendElement = libmei.Rend();
        libmei.AddChild(element, rendElement);
        for each Name attName in styleAttributes
        {
            libmei.AddAttribute(rendElement, attName, styleAttributes[attName]);
        }
        libmei.SetText(rendElement, substitutedText);
    }
}  //$end

function InitTextHandlers() {
    // QUESTION: We could also take an argument and throw all text handlers from
    // extensions into the same dictionary

    Self._property:TextHandlers = CreateDictionary(
        'text.staff.expression', 'ExpressionTextHandler',
        'text.system.page_aligned.title', 'PageTitleHandler',
        'text.system.page_aligned.subtitle', 'PageTitleHandler',
        'text.system.page_aligned.composer', 'PageComposerTextHandler',
        'text.system.tempo', 'TempoTextHandler',
        'text.staff.space.figuredbass', 'FiguredBassTextHandler'
    );

    Self._property:TextSubstituteMap = CreateDictionary(
        'Title', CreateSparseArray('Title'),
        'Subtitle', CreateSparseArray('Title', CreateDictionary('type', 'subordinate')),
        'Dedication', CreateSparseArray('Dedication'),
        // <composer>, <arranger>, <lyricist>, <userRestrict> and <publisher>
        // are only allowed in a few places, e.g. metadata or title pages.
        // We therfore use more generic elements
        'Composer', CreateSparseArray('PersName', CreateDictionary('role', 'Composer')),
        'Arranger', CreateSparseArray('PersName', CreateDictionary('role', 'Arranger')),
        'Lyricist', CreateSparseArray('PersName', CreateDictionary('role', 'Lyricist')),
        'Artist', CreateSparseArray('PersName', CreateDictionary('role', 'Artist')),
        // <useRestrict> is only allowed on <titlePage>, so use generic element
        'Copyright', CreateSparseArray('Seg', CreateDictionary('type', 'Copyright')),
        // <publisher> is only allowed in a few places, so use generic element
        // We don't even know if it's a person or an institution
        'Publisher', CreateSparseArray('Seg', CreateDictionary('type', 'Publisher')),
        'MoreInfo', CreateSparseArray('Seg', CreateDictionary('type', 'MoreInfo')),
        'PartName', CreateSparseArray('Seg', CreateDictionary('type', 'PartName'))
    );
}  //$end

function HandleText (textObject) {
    // TODO: Move InitTextHandlers() call to a global initialization function
    InitTextHandlers();
    if (null != Self._property:Extension and null != Extension.TextHandlers)
    {
        // TODO: We need to check for both StyleId *and* StyleAsText so we can
        // handle custom styles
        textHandler = Extension.TextHandlers[textObject.StyleId];
        if (null != textHandler)
        {
            return Extension.@textHandler(textObject);
        }
    }

    textHandler = TextHandlers[textObject.StyleId];
    if (null != textHandler)
    {
        return @textHandler(textObject);
    }
}  //$end

function ExpressionTextHandler (textObject) {
    dynam = AddBarObjectInfoToElement(textObject, libmei.Dynam());
    AddFormattedText(dynam, textObject);
    return dynam;
}  //$end

function PageTitleHandler (textObject) {
    anchoredText = libmei.AnchoredText();
    title = libmei.Title();
    if (textObject.StyleId = 'text.system.page_aligned.subtitle')
    {
        libmei.AddAttribute(title, 'type', 'subordinate');
    }

    libmei.AddChild(anchoredText, title);
    AddFormattedText(title, textObject);

    return anchoredText;
}  //$end

function PageComposerTextHandler (textObject) {
    // 'text.system.page_aligned.composer'
    return AddBarObjectInfoToElement(textObject, CreateAnchoredText(textObject));
}  //$end

function TempoTextHandler (textObject) {
    // 'text.system.tempo'
    tempo = libmei.Tempo();
    libmei.AddChild(tempo, CreateAnchoredText(textObject));
    return tempo;
}  //$end

function FiguredBassTextHandler (textObject) {
    // 'text.staff.space.figuredbass'
    harm = AddBarObjectInfoToElement(textObject, libmei.Harm());
    fb = libmei.Fb();
    libmei.AddChild(harm, fb);
    ConvertFbFigures(fb, textObject);
    return harm;
}  //$end

function CreateAnchoredText (textObj) {
    //$module(ExportConverters.mss)
    anchoredText = libmei.AnchoredText();
    AddFormattedText(anchoredText, textObj);
    return anchoredText;
}  //$end

function AddFormattedText (parentElement, textObj) {
    textWithFormatting = textObj.TextWithFormatting;
    if (textWithFormatting.NumChildren < 2 and CharAt(textWithFormatting[0], 0) != '\\')
    {
        libmei.SetText(parentElement, textObj.Text);
        return null;
    }

    nodes = CreateSparseArray();

    state = CreateDictionary(
        'currentText', null,
        'rendAttributes', CreateDictionary(),
        'rendFlags', CreateDictionary(),
        // TODO: Also track the active character style (mainly
        // `\ctext.character.musictext\`, and custom styles)
        'nodes', nodes,
        'paragraphs', null
    );

    for each component in textObj.TextWithFormatting
    {
        switch (Substring(component, 0, 2))
        {
            case ('\\n')
            {
                PushStyledText(state);
                nodes.Push(libmei.Lb());
            }
            case ('\\N')
            {
                PushStyledText(state);
                // TODO: Add <p> if it is allowed within parentElement (use libmei.GetName())
                nodes.Push(libmei.Lb());
            }
            case ('\\B')
            {
                SwitchTextStyle(state, 'fontweight', 'bold');
            }
            case ('\\b')
            {
                SwitchTextStyle(state, 'fontweight', 'normal');
            }
            case ('\\I')
            {
                SwitchTextStyle(state, 'fontstyle', 'italic');
            }
            case ('\\i')
            {
                SwitchTextStyle(state, 'fontstyle', 'normal');
            }
            case ('\\U')
            {
                SwitchTextStyle(state, 'rend', 'underline', true);
            }
            case ('\\u')
            {
                SwitchTextStyle(state, 'rend', 'underline', false);
            }
            case ('\\f')
            {
                SwitchFont(state, GetTextCommandArg(component));
            }
            case ('\\c')
            {
                // TODO: Can we sensibly handle a character style change? The
                // only built-in one seem to be `text.character.musictext`. We
                // might want to allow Extensions to handle custom character
                // styles.
                ;
            }
            case ('\\s')
            {
                fontsize = ConvertOffsetsToMEI(GetTextCommandArg(component));
                SwitchTextStyle(state, 'fontsize', fontsize);
            }
            case ('\\v')
            {
                // Vertical scale change (vertical stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\h')
            {
                // Horizontal scale change (horizontal stretching). Probably not
                // possible to handle
                ;
            }
            case ('\\t')
            {
                // Tracking. Probably not possible to handle.
                ;
            }
            case ('\\p')
            {
                SwitchBaselineAdjust(state, GetTextCommandArg(component));
            }
            case ('\\$') {
                AppendTextSubstitute(state, GetTextCommandArg(component));
            }
            case ('\\\\')
            {
                // According to the documentation, 'backslashes themselves are
                // represented by \\ , to avoid conflicting with the above
                // commands'. Though that does not seem to work, let's just
                // assume it does in case Avid fixes this.

                // We strip one leading backspace.
                state.currentText = state.currentText & Substring(component, 1);
            }
            default
            {
                // This is regular text
                state.currentText = state.currentText & component;
            }
        }
    }

    PushStyledText(state);

    nodeCount = nodes.Length;
    precedingElement = null;

    nodeIndex = 0;
    while (nodeIndex < nodeCount)
    {
        node = nodes[nodeIndex];
        if (IsObject(node))
        {
            // We have an element
            libmei.AddChild(parentElement, node);
            precedingElement = node;
        }
        else
        {
            // We have a text node
            text = node;
            // If there are multiple adjacent text nodes, we need to join them
            while (nodeIndex < nodeCount and not IsObject(nodes[nodeIndex + 1])) {
                nodeIndex = nodeIndex + 1;
                text = text & nodes[nodeIndex];
            }

            if (precedingElement = null)
            {
                libmei.SetText(parentElement, text);
            }
            else
            {
                libmei.SetTail(precedingElement, text);
            }
        }
        nodeIndex = nodeIndex + 1;
    }
}  //$end

function NewTextParagraph (state) {
    // TODO!
    ;
}  //$end

function GetTextCommandArg (command) {
    // Remove leading part, e.g. the '\$' or '\s' and trailing '\'
    return Substring(command, 2, Length(command) - 3);
}  //$end

function SwitchBaselineAdjust (state, param) {
    sup = (param = 'superscript');
    sub = (param = 'subscript');
    if (sup != state.rendFlags['sup'] or sub != state.rendFlags['sub']) {
        // Style changed, push the previous text before changing the style
        PushStyledText(state);
    }
    state.rendFlags['sup'] = sup;
    state.rendFlags['sub'] = sub;
}  //$end

function ResetTextStyles (state, infoOnly) {
    // If `infoOnly` is `true`, does not make any changes, only tells us if
    // there are re-settable styles
    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            if (infoOnly and state.rendAttributes[attName] != null)
            {
                return true;
            }
            state.rendAttributes[attName] = null;
        }
    }

    if (null != state.rendFlags)
    {
        for each Name flagName in state.rendFlags
        {
            if (infoOnly and state.rendFlags[flagName])
            {
                return true;
            }
            state.rendFlags[flagName] = false;
        }
    }
    return false;
}  //$end

function SwitchFont (state, fontName) {
    if (fontName = '_')
    {
        // Before resetting the style, we have to add text preceding the '\f_\'
        // style reset – but only if the style reset actually changes something.
        if (ResetTextStyles(state, true))
        {
            PushStyledText(state);
            ResetTextStyles(state, false);
        }
    }
    else
    {
        SwitchTextStyle(state, 'fontfam', fontName);
    }
}  //$end

function SwitchTextStyle (state, attName, value) {
    if (state.rendAttributes[attName] != value)
    {
        // Style changes, so append current text before modifying style state
        PushStyledText(state);
    }
    state.rendAttributes[attName] = value;
}  //$end

function SwitchRendFlags (state, flagName, value) {
    if (state.rendFlags[flagName] != value)
    {
        PushStyledText(state);
    }
    state.rendFlags[flagName] = value;
}  //$end

function PushStyledText (state) {
    if (state.currentText = '')
    {
        return null;
    }

    styleAttributes = GetStyleAttributes(state);
    if (null = styleAttributes)
    {
        // We attach unstyled text without wrapping it in <rend>
        state.nodes.Push(state.currentText);
    }
    else
    {
        rend = libmei.Rend();
        for each Name attName in styleAttributes {
            libmei.AddAttribute(rend, attName, styleAttributes[attName]);
        }
        libmei.SetText(rend, state.currentText);
        state.nodes.Push(rend);
    }

    state.currentText = '';
}  //$end

function GetStyleAttributes (state) {
    rendAttributes = null;

    if (null != state.rendAttributes)
    {
        for each Name attName in state.rendAttributes
        {
            value = state.rendAttributes[attName];
            if (null != value)
            {
                if (null = rendAttributes) {
                    rendAttributes = CreateDictionary();
                }
                rendAttributes[attName] = value;
            }
        }
    }

    if (null != state.rendFlags)
    {
        rendAttValue = '';
        for each Name flagName in state.rendFlags
        {
            flagActive = state.rendFlags[flagName];
            if (flagActive)
            {
                rendAttValue = rendAttValue & flagName & ' ';
            }
        }
        if (rendAttValue != '')
        {
            if (null = rendAttributes) {
                rendAttributes = CreateDictionary();
            }
            rendAttributes['rend'] = rendAttValue;
        }
    }

    return rendAttributes;
}  //$end

function AppendTextSubstitute (state, substituteName) {
    score = Self._property:ActiveScore;

    textSubstituteInfo = TextSubstituteMap[substituteName];
    if (null = textSubstituteInfo)
    {
        // No known substitution. Sibelius renders those literally.
        state.currentText = state.currentText & '\\$' & substituteName & '\\';
        return null;
    }

    substitutedText = score.@substituteName;
    if (substitutedText = '') {
        // TODO: Also check for all-whitespace text
        return null;
    }

    element = DataToMEI(textSubstituteInfo);
    state.nodes.Push(element);

    styleAttributes = GetStyleAttributes(state);
    rendElement = null;
    if (null = styleAttributes)
    {
        libmei.SetText(element, substitutedText);
    }
    else
    {
        rendElement = libmei.Rend();
        libmei.AddChild(element, rendElement);
        for each Name attName in styleAttributes
        {
            libmei.AddAttribute(rendElement, attName, styleAttributes[attName]);
        }
        libmei.SetText(rendElement, substitutedText);
    }
}  //$end


Deal with spelling errors in Natural Earth

@text_font_transport_bold: 'Arial Unicode MS Bold';
@text_font_physical_bold: 'Arial Unicode MS Bold';
@text_font_administrative: 'Arial Unicode MS Regular';
@text_font_administrative_bold: 'Arial Unicode MS Bold';
@text_font_water: 'Arial Unicode MS Italic';
@text_font_water_bold: 'Arial Unicode MS Bold Italic';
@text_font_city: 'Arial Unicode MS Regular';
@text_font_city_bold: 'Arial Unicode MS Bold';
@text_font_poi_bold: 'Arial Unicode MS Italic'; // n-dash is broken in Bold Italic

@label_color_transport: #000;
@label_color_transport_halo: #fff;
@label_color_physical: #000;
@label_color_physical_halo: #fff;
@label_color_administrative: #000;
@label_color_administrative_halo: #fff;
@label_color_city: #000;
@label_color_city_halo: #fff;
@label_color_poi: #000;
@label_color_poi_halo: #fff;

@text_font_size_xxsm: 10;
@text_font_size_xsm: 12;
@text_font_size_sm: 13;
@text_font_size_medium: 14;
@text_font_size_medium_plus: 16;
@text_font_size_large: 18;
@text_font_halo_radius_sm: 1;
@text_font_halo_radius_large: 2;

#minor_road_labels {
  text-name: "[name]";
  text-face-name: @text_font_transport_bold;
  text-placement: line;
  text-max-char-angle-delta: 30;
  text-fill: @label_color_transport;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_transport_halo;
  text-avoid-edges: true;

  [zoom=16] {
    text-dy: 10;
    text-spacing: 124;
    text-size: @text_font_size_xxsm;
    text-halo-radius: @text_font_halo_radius_large;
  }
  [zoom=17] {
    text-dy: 13;
    text-spacing: 180;
    text-size: @text_font_size_xsm;
    text-halo-radius: @text_font_halo_radius_large;
  }
  [zoom>=18] {
    text-size: @text_font_size_xsm;
    text-spacing: 400;
    text-halo-radius: @text_font_halo_radius_large;
  }
}

#major_road_labels {
  text-name: "[name]";
  text-face-name: @text_font_transport_bold;
  text-placement: line;
  text-max-char-angle-delta: 30;
  text-fill: @label_color_transport;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_transport_halo;
  text-spacing: 100;
  text-avoid-edges: true;

  [zoom>=16][highway='primary'] {
	text-halo-radius: @text_font_halo_radius_large;
  }
  [is_tunnel=1][zoom>=15] {
	text-fill: #777;
  }
  [zoom=12] {
    text-dy: 7;
    text-size: @text_font_size_xsm;
    text-min-distance: 4;
  }
  [zoom=13] {
    text-dy: 8;
    text-min-distance: 5;
    [highway='trunk'] {
		text-size: @text_font_size_sm;
    }
    [highway='primary'] {
		text-size: 13;
    }
  }

  [zoom=14] {
    text-min-distance: 5;
    [highway='trunk'],[highway='primary'] {
		text-dy: 9;
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-dy: 7;
      	text-size: @text_font_size_xsm;
        text-halo-radius: 1.5;
    }
  }

  [zoom=15] {
    text-min-distance: 10;
    [highway='trunk'],[highway='primary'] {
		text-dy: @text_font_size_xsm;
      	text-size: 15;
    }
    [highway='secondary'],[highway='tertiary'] {
		text-dy: 11;
      	text-size: @text_font_size_sm;
    }
  }

  [zoom=16] {
    text-min-distance: 12;
    text-dy: 13;
    [highway='trunk'],[highway='primary'] {
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'],[highway='tertiary'] {
      	text-spacing: 124;
      	text-size: @text_font_size_sm;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }

  [zoom=17] {
    text-min-distance: 12;
    [highway='trunk'] {
		text-dy: 16;
      	text-size: @text_font_size_medium_plus;
    }
    [highway='primary'] {
		text-dy: 14;
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-dy: 14;
      	text-spacing: 180;
      	text-size: @text_font_size_medium;
      	text-halo-radius: @text_font_halo_radius_large;
    }
    [highway='tertiary'] {
		text-dy: 13;
      	text-spacing: 180;
      	text-size: @text_font_size_xsm;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }

  [zoom>=18] {
    text-min-distance: 12;
    [highway='trunk'] {
		text-size: @text_font_size_medium_plus;
    }
    [highway='primary'] {
		text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-size: @text_font_size_medium;
		text-spacing: 300;
		text-halo-radius: @text_font_halo_radius_large;
    }
    [highway='tertiary'] {
        text-size: @text_font_size_xsm;
        text-spacing: 400;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }
}

#poi_station_labels {
  [zoom>=16][railway='station'] {
    shield-name: "[label]";
    shield-face-name: @text_font_transport_bold;
    shield-fill: white;
    shield-size: 12;
    shield-file: url('images/subway_shield_small.svg');
  }
}

#water-bodies-labels-low,
#water-bodies-labels-med,
#water-bodies-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
 	text-name: "[name]";
	text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;
    text-fill: @label_color_physical_halo;
    text-halo-fill: @label_color_physical;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }
    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=15] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#green-areas-labels-low,
#green-areas-labels-med,
#green-areas-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
 	text-name: "[name]";
	text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;

    text-fill: @label_color_physical;
    text-halo-fill: @label_color_physical_halo;

    text-line-spacing: -1;
    text-min-distance: 10;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }

    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=16] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#continents[zoom>=1][zoom<3]
{
  	text-name: "[name]";
    text-face-name: @text_font_physical_bold;
    text-wrap-width: 32;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical;
    text-halo-radius: 3;
    text-halo-fill: @label_color_physical_halo;
}

#admin1-labels-50m-z4 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z4]";
    text-size:  @text_font_size_xsm;
}

#admin1-labels-50m-z5 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z5]";
    text-size:  @text_font_size_medium_plus;
}

#admin1-labels-50m-z6 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z6]";
    text-size:  @text_font_size_large;
}

#admin1-labels-50m-z7 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z7]";
    text-size:  @text_font_size_large;
}

#admin0-labels-z3[longfrom>3] {
  	text-name: "[shortname]";
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-size: @text_font_size_sm;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
  	text-min-distance: 1;
}

#admin0-labels-z3[longfrom<=3] {
  	text-name: "[name]";
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-size: @text_font_size_sm;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z4 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z5 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium_plus;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z6 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_large;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

// HACK! All the problematic water bodies with accents
// e.g. "Bahia de Campeche" with an accented i,
// have an empty "changed" string. So abuse this for now.

#ne_110m_geography_marine_polys[zoom=2][scalerank=0][changed!=''],
#ne_110m_geography_marine_polys[zoom=3][changed!=''],
#ne_50m_geography_marine_polys[zoom=4][scalerank<4][changed!=''] {
    text-name: [name];
  	[namealt!=''] {
  		text-name: [name] + '\n(' + [namealt] + ')';
    }
	text-face-name: @text_font_water_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical_halo;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_physical;
}

#ne_50m_geography_marine_polys[zoom=5][changed!=''],
#ne_10m_geography_marine_polys[zoom>=6][zoom<=8][changed!='']
{
  	text-name: [name];
  	[namealt!=''] {
  		text-name: [name] + '\n(' + [namealt] + ')';
    }
    [name = 'Hecate Straight'] {
      text-name: 'Hecate Strait' + [namealt]; // Becase we know namealt is empty
    }
    [name = 'Queen Charlotte Straight'] {
      text-name: 'Queen Charlotte Strait' + [namealt]; // Becase we know namealt is empty
    }
    text-face-name: @text_font_water;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical_halo;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_physical;
}

#city_labels_z4,
#city_labels_z5,
#city_labels_z6 {
  text-name: [name];
  text-face-name: @text_font_city;
  text-fill: @label_color_city;
  text-vertical-alignment: bottom;
  text-halo-radius: @text_font_halo_radius_large;
  text-halo-fill: @label_color_city_halo;
  text-min-distance: 0;

  [justified='left'] {
    text-horizontal-alignment: middle;
    text-dx: -5;
  }

  [justified='right'] {
    text-horizontal-alignment: middle;
    text-dx: 5;
  }

  [zoom>=4]  {
    text-size: @text_font_size_xxsm;
  }

  [zoom>=5] {
    text-size: @text_font_size_xsm;
  }

  [font_size=14] {
    text-size: @text_font_size_medium;
  }

  [font_size=16] {
    text-size: @text_font_size_medium_plus;
  }

  [font_size=18] {
    text-size: @text_font_size_large;
  }
}

#city_labels_z7,
#city_labels_z8, {
  text-name: "[name]";
  text-face-name: @text_font_city_bold;
  text-fill: @label_color_city;
  text-halo-radius: @text_font_halo_radius_large;
  text-halo-fill: @label_color_city_halo;
  text-size: @text_font_size_sm;

  [zoom=7] {
    text-size: @text_font_size_xsm;
  }

  [font_size=18] {
    text-size: @text_font_size_large;
  }

  [font_size=20] {
    text-size: @text_font_size_large;
  }

  [justified='left'] {
    text-horizontal-alignment: middle;
    text-dx: -5;
  }

  [justified='right'] {
    text-horizontal-alignment: middle;
    text-dx: 5;
  }
}

#city_labels_z9,
#city_labels_z10,
#city_labels_z11,
#city_labels_z12, {
  	text-name: "[name]";
    text-face-name: @text_font_city_bold;
    text-fill: @label_color_city;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_city_halo;
	text-size: @text_font_size_sm;
    [font_size=20] { text-size: @text_font_size_large; }
}

#city_points_z4,
#city_points_z5,
#city_points_z6,
#city_points_z7,
#city_points_z8 {
  	marker-ignore-placement: true;
  	marker-width: 7;
  	marker-fill: black;
  	marker-line-color: white;
  	marker-line-width: 2;
}

#airports[zoom>=10][zoom<=13] {
    marker-width: 18;
	marker-file: url('images/airplane.svg');
}

#airports[zoom>=13][scalerank<=12]
{
  	text-name: "[name]";
    [name="Tacoma Int'l"] {
      text-name: "Seattle-" + [name];
    }
    text-face-name: @text_font_poi_bold;
    text-fill: @label_color_poi;
    text-size: @text_font_size_medium;
    text-halo-fill: @label_color_poi_halo;
    text-halo-radius: @text_font_halo_radius_large;
    text-wrap-width: 128;
    text-dy: 14;
    text-allow-overlap: true;

  	[zoom>=14] {
    	text-dy: 0;
    }
}
#airports {
      text-name: "[name]";
      text-face-name: @text_font_poi_bold;
      text-fill: red;
  }

@text_font_transport_bold: 'Arial Unicode MS Bold';
@text_font_physical_bold: 'Arial Unicode MS Bold';
@text_font_administrative: 'Arial Unicode MS Regular';
@text_font_administrative_bold: 'Arial Unicode MS Bold';
@text_font_water: 'Arial Unicode MS Italic';
@text_font_water_bold: 'Arial Unicode MS Bold Italic';
@text_font_city: 'Arial Unicode MS Regular';
@text_font_city_bold: 'Arial Unicode MS Bold';
@text_font_poi_bold: 'Arial Unicode MS Italic'; // n-dash is broken in Bold Italic

@label_color_transport: #000;
@label_color_transport_halo: #fff;
@label_color_physical: #000;
@label_color_physical_halo: #fff;
@label_color_administrative: #000;
@label_color_administrative_halo: #fff;
@label_color_city: #000;
@label_color_city_halo: #fff;
@label_color_poi: #000;
@label_color_poi_halo: #fff;

@text_font_size_xxsm: 10;
@text_font_size_xsm: 12;
@text_font_size_sm: 13;
@text_font_size_medium: 14;
@text_font_size_medium_plus: 16;
@text_font_size_large: 18;
@text_font_halo_radius_sm: 1;
@text_font_halo_radius_large: 2;

#minor_road_labels {
  text-name: "[name]";
  text-face-name: @text_font_transport_bold;
  text-placement: line;
  text-max-char-angle-delta: 30;
  text-fill: @label_color_transport;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_transport_halo;
  text-avoid-edges: true;

  [zoom=16] {
    text-dy: 10;
    text-spacing: 124;
    text-size: @text_font_size_xxsm;
    text-halo-radius: @text_font_halo_radius_large;
  }
  [zoom=17] {
    text-dy: 13;
    text-spacing: 180;
    text-size: @text_font_size_xsm;
    text-halo-radius: @text_font_halo_radius_large;
  }
  [zoom>=18] {
    text-size: @text_font_size_xsm;
    text-spacing: 400;
    text-halo-radius: @text_font_halo_radius_large;
  }
}

#major_road_labels {
  text-name: "[name]";
  text-face-name: @text_font_transport_bold;
  text-placement: line;
  text-max-char-angle-delta: 30;
  text-fill: @label_color_transport;
  text-halo-radius: @text_font_halo_radius_sm;
  text-halo-fill: @label_color_transport_halo;
  text-spacing: 100;
  text-avoid-edges: true;

  [zoom>=16][highway='primary'] {
	text-halo-radius: @text_font_halo_radius_large;
  }
  [is_tunnel=1][zoom>=15] {
	text-fill: #777;
  }
  [zoom=12] {
    text-dy: 7;
    text-size: @text_font_size_xsm;
    text-min-distance: 4;
  }
  [zoom=13] {
    text-dy: 8;
    text-min-distance: 5;
    [highway='trunk'] {
		text-size: @text_font_size_sm;
    }
    [highway='primary'] {
		text-size: 13;
    }
  }

  [zoom=14] {
    text-min-distance: 5;
    [highway='trunk'],[highway='primary'] {
		text-dy: 9;
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-dy: 7;
      	text-size: @text_font_size_xsm;
        text-halo-radius: 1.5;
    }
  }

  [zoom=15] {
    text-min-distance: 10;
    [highway='trunk'],[highway='primary'] {
		text-dy: @text_font_size_xsm;
      	text-size: 15;
    }
    [highway='secondary'],[highway='tertiary'] {
		text-dy: 11;
      	text-size: @text_font_size_sm;
    }
  }

  [zoom=16] {
    text-min-distance: 12;
    text-dy: 13;
    [highway='trunk'],[highway='primary'] {
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'],[highway='tertiary'] {
      	text-spacing: 124;
      	text-size: @text_font_size_sm;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }

  [zoom=17] {
    text-min-distance: 12;
    [highway='trunk'] {
		text-dy: 16;
      	text-size: @text_font_size_medium_plus;
    }
    [highway='primary'] {
		text-dy: 14;
      	text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-dy: 14;
      	text-spacing: 180;
      	text-size: @text_font_size_medium;
      	text-halo-radius: @text_font_halo_radius_large;
    }
    [highway='tertiary'] {
		text-dy: 13;
      	text-spacing: 180;
      	text-size: @text_font_size_xsm;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }

  [zoom>=18] {
    text-min-distance: 12;
    [highway='trunk'] {
		text-size: @text_font_size_medium_plus;
    }
    [highway='primary'] {
		text-size: @text_font_size_medium;
    }
    [highway='secondary'] {
		text-size: @text_font_size_medium;
		text-spacing: 300;
		text-halo-radius: @text_font_halo_radius_large;
    }
    [highway='tertiary'] {
        text-size: @text_font_size_xsm;
        text-spacing: 400;
      	text-halo-radius: @text_font_halo_radius_large;
    }
  }
}

#poi_station_labels {
  [zoom>=16][railway='station'] {
    shield-name: "[label]";
    shield-face-name: @text_font_transport_bold;
    shield-fill: white;
    shield-size: 12;
    shield-file: url('images/subway_shield_small.svg');
  }
}

#water-bodies-labels-low,
#water-bodies-labels-med,
#water-bodies-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
 	text-name: "[name]";
	text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;
    text-fill: @label_color_physical_halo;
    text-halo-fill: @label_color_physical;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }
    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=15] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#green-areas-labels-low,
#green-areas-labels-med,
#green-areas-labels-high {
  [zoom=9][area>100000000],
  [zoom=10][area>100000000],
  [zoom=11][area>25000000],
  [zoom=12][area>5000000],
  [zoom=13][area>2000000],
  [zoom=14][area>200000],
  [zoom=15][area>50000],
  [zoom=16][area>10000],
  [zoom>=17] {
 	text-name: "[name]";
	text-face-name: @text_font_water;
    text-placement: interior;
    text-max-char-angle-delta: 30;
    text-wrap-width: 40;
    text-halo-radius: @text_font_halo_radius_large;

    text-fill: @label_color_physical;
    text-halo-fill: @label_color_physical_halo;

    text-line-spacing: -1;
    text-min-distance: 10;
    text-size: @text_font_size_xsm;

    [zoom>9][zoom<12] {
      text-spacing: 200;
      text-wrap-width: 50;
    }

    [zoom=12] {
      text-size: @text_font_size_xsm;
      text-spacing: 200;
      text-wrap-width: 70;
    }
    [zoom=13] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=14] {
      text-size: @text_font_size_xsm;
      text-spacing: 100;
      text-wrap-width: 70;
    }
    [zoom>=16] {
      text-size: @text_font_size_sm;
      text-spacing: 100;
      text-wrap-width: 40;
    }
  }
}

#continents[zoom>=1][zoom<3]
{
  	text-name: "[name]";
    text-face-name: @text_font_physical_bold;
    text-wrap-width: 32;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical;
    text-halo-radius: 3;
    text-halo-fill: @label_color_physical_halo;
}

#admin1-labels-50m-z4 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z4]";
    text-size:  @text_font_size_xsm;
}

#admin1-labels-50m-z5 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z5]";
    text-size:  @text_font_size_medium_plus;
}

#admin1-labels-50m-z6 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z6]";
    text-size:  @text_font_size_large;
}

#admin1-labels-50m-z7 {
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
    text-name: "[label_z7]";
    text-size:  @text_font_size_large;
}

#admin0-labels-z3[longfrom>3] {
  	text-name: "[shortname]";
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-size: @text_font_size_sm;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
  	text-min-distance: 1;
}

#admin0-labels-z3[longfrom<=3] {
  	text-name: "[name]";
    text-face-name: @text_font_administrative;
    text-wrap-width: 80;
    text-size: @text_font_size_sm;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z4 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z5 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium_plus;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

#admin0-labels-z6 {
  	text-name: "[name]";
    text-face-name: @text_font_administrative_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_large;
    text-fill: @label_color_administrative;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_administrative_halo;
}

// HACK! All the problematic water bodies with accents
// e.g. "Bahia de Campeche" with an accented i,
// have an empty "changed" string. So abuse this for now.

#ne_110m_geography_marine_polys[zoom=2][scalerank=0][changed!=''],
#ne_110m_geography_marine_polys[zoom=3][changed!=''],
#ne_50m_geography_marine_polys[zoom=4][scalerank<4][changed!=''] {
    text-name: [name];
  	[namealt!=''] {
  		text-name: [name] + '\n(' + [namealt] + ')';
    }
	text-face-name: @text_font_water_bold;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical_halo;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_physical;
}

#ne_50m_geography_marine_polys[zoom=5][changed!=''],
#ne_10m_geography_marine_polys[zoom>=6][zoom<=8][changed!='']
{
  	text-name: [name];
  	[namealt!=''] {
  		text-name: [name] + '\n(' + [namealt] + ')';
    }
    text-face-name: @text_font_water;
    text-wrap-width: 80;
    text-size: @text_font_size_medium;
    text-fill: @label_color_physical_halo;
    text-halo-radius: @text_font_halo_radius_sm;
    text-halo-fill: @label_color_physical;
}

#city_labels_z4,
#city_labels_z5,
#city_labels_z6 {
  text-name: [name];
  text-face-name: @text_font_city;
  text-fill: @label_color_city;
  text-vertical-alignment: bottom;
  text-halo-radius: @text_font_halo_radius_large;
  text-halo-fill: @label_color_city_halo;
  text-min-distance: 0;

  [justified='left'] {
    text-horizontal-alignment: middle;
    text-dx: -5;
  }

  [justified='right'] {
    text-horizontal-alignment: middle;
    text-dx: 5;
  }

  [zoom>=4]  {
    text-size: @text_font_size_xxsm;
  }

  [zoom>=5] {
    text-size: @text_font_size_xsm;
  }

  [font_size=14] {
    text-size: @text_font_size_medium;
  }

  [font_size=16] {
    text-size: @text_font_size_medium_plus;
  }

  [font_size=18] {
    text-size: @text_font_size_large;
  }
}

#city_labels_z7,
#city_labels_z8, {
  text-name: "[name]";
  text-face-name: @text_font_city_bold;
  text-fill: @label_color_city;
  text-halo-radius: @text_font_halo_radius_large;
  text-halo-fill: @label_color_city_halo;
  text-size: @text_font_size_sm;

  [zoom=7] {
    text-size: @text_font_size_xsm;
  }

  [font_size=18] {
    text-size: @text_font_size_large;
  }

  [font_size=20] {
    text-size: @text_font_size_large;
  }

  [justified='left'] {
    text-horizontal-alignment: middle;
    text-dx: -5;
  }

  [justified='right'] {
    text-horizontal-alignment: middle;
    text-dx: 5;
  }
}

#city_labels_z9,
#city_labels_z10,
#city_labels_z11,
#city_labels_z12, {
  	text-name: "[name]";
    text-face-name: @text_font_city_bold;
    text-fill: @label_color_city;
    text-halo-radius: @text_font_halo_radius_large;
    text-halo-fill: @label_color_city_halo;
	text-size: @text_font_size_sm;
    [font_size=20] { text-size: @text_font_size_large; }
}

#city_points_z4,
#city_points_z5,
#city_points_z6,
#city_points_z7,
#city_points_z8 {
  	marker-ignore-placement: true;
  	marker-width: 7;
  	marker-fill: black;
  	marker-line-color: white;
  	marker-line-width: 2;
}

#airports[zoom>=10][zoom<=13] {
    marker-width: 18;
	marker-file: url('images/airplane.svg');
}

#airports[zoom>=13][scalerank<=12]
{
  	text-name: "[name]";
    [name="Tacoma Int'l"] {
      text-name: "Seattle-" + [name];
    }
    text-face-name: @text_font_poi_bold;
    text-fill: @label_color_poi;
    text-size: @text_font_size_medium;
    text-halo-fill: @label_color_poi_halo;
    text-halo-radius: @text_font_halo_radius_large;
    text-wrap-width: 128;
    text-dy: 14;
    text-allow-overlap: true;

  	[zoom>=14] {
    	text-dy: 0;
    }
}
#airports {
      text-name: "[name]";
      text-face-name: @text_font_poi_bold;
      text-fill: red;
  }


Oops

Oops

git-svn-id: 52b2958d923a603b3f48d22aabe6b5bf40478d2a@252 dbea3d40-3153-0410-b551-57805770c6e6

Map
{
    map-bgcolor: #8cb6d3;
}

.coast.edge.outer
{
    line-width: 13;
    line-color: #a1cbea;
    line-join: round;
}

.coast.edge.inner
{
    line-width: 5;
    line-color: #7eaac1;
    line-join: round;
}

.coast.edge.outer[zoom<=12] { line-width: 9; }
.coast.edge.inner[zoom<=12] { line-width: 3; }

.water.area
{
    line-width: 2;
    line-color: #7eaac1;
    polygon-fill: #8cb6d3;
    line-join: round;
}

.water.line
{
    line-color: #7eaac1;
    line-join: round;
}

.water.line[zoom>=13],
.water.line[zoom>=15][waterway=stream]
{
    line-color: #8cb6d3;

    outline-width: 1;
    outline-color: #7eaac1;
    outline-join: round;
}

.water.line[zoom>=11][zoom<=12] { line-width: 2; }
.water.line[zoom>=11][zoom<=12][waterway=stream] { line-width: 1; }

.water.line[zoom=13] { line-width: 3; }
.water.line[zoom=13][waterway=stream] { line-width: 1; }

.water.line[zoom=14] { line-width: 5; }
.water.line[zoom=14][waterway=stream] { line-width: 2; }

.water.line[zoom=15] { line-width: 7; }
.water.line[zoom=15][waterway=stream] { line-width: 3; }

.water.line[zoom=16] { line-width: 9; }
.water.line[zoom=16][waterway=stream] { line-width: 5; }

.water.line[zoom>=17] { line-width: 12; }
.water.line[zoom>=17][waterway=stream] { line-width: 8; }

.coast.fill
{
    polygon-fill: #dceee9;
    /*
    line-width: 1;
    line-color: #dceee9;
    */
}

.citylike.area
{
    polygon-fill: #d0d0d0;
}

/*
.citylike.area[amenity=school],
.citylike.area[amenity=college],
.citylike.area[amenity=university]
{
    polygon-fill: #d2caba;
}
*/

.parklike.area
{
    polygon-fill: #91b156;
}

.parklike.area[zoom>=16][leisure!=pitch][leisure!=track][landuse!=cemetery],
.parklike.area[zoom>=14][zoom<=15][leisure!=pitch][leisure!=track][landuse!=cemetery][size=large]
{
    polygon-pattern-file: url('img/trees-z.png');
}

.parklike.area[zoom>=11]
{
    line-width: 1;
    line-color: #6dbe3c;
}

.parklike.area[landuse=cemetery]
{
    line-color: #799a67;
    polygon-fill: #94b580;
}

.parklike.area[zoom>=16][landuse=cemetery],
.parklike.area[zoom=15][landuse=cemetery][size=large]
{
    polygon-pattern-file: url('img/graveyard-z.png');
}

.building.area[zoom>=13]
{
    polygon-fill: #aaaaaa;
}

.building.area[zoom>=15]
{
    line-width: 1;
    line-color: #808080;
}

.water.label name,
.parklike.label name,
.citylike.label[amenity!=parking] name,
.building.label name
{
    text-face-name: "DejaVu Sans Book";
    text-fill: #000;
    text-placement: point;
    text-halo-radius: 2;
}

.water.label[zoom>=13][zoom<=15][size=large] name,
.parklike.label[zoom>=13][zoom<=15][size=large] name,
.citylike.label[zoom>=13][zoom<=15][size=large][amenity!=parking] name,
.building.label[zoom>=13][zoom<=15][size=large] name,
.water.label[zoom>=15][zoom<=16][size=medium] name,
.parklike.label[zoom>=15][zoom<=16][size=medium] name,
.citylike.label[zoom>=15][zoom<=16][size=medium][amenity!=parking] name,
.building.label[zoom>=15][zoom<=16][size=medium] name,
.water.label[zoom=16][size=small] name,
.parklike.label[zoom=16][size=small] name,
.citylike.label[zoom=16][size=small][amenity!=parking] name,
.building.label[zoom=16][size=small] name
{
    text-size: 9;
    text-wrap-width: 50;
}

.building.label[zoom>=17][amenity=school],
.citylike.label[zoom>=17][amenity=school]
{
    point-file: url('img/icons/24x24/symbol/landmark/amenity=school.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=school],
.citylike.label[zoom>=15][zoom<=16][amenity=school]
{
    point-file: url('img/icons/16x16/symbol/landmark/amenity=school.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=school],
.citylike.label[zoom=14][amenity=school]
{
    point-file: url('img/icons/12x12/symbol/landmark/amenity=school.png');
}

.building.label[zoom>=17][amenity=police],
.citylike.label[zoom>=17][amenity=police]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=police.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=police],
.citylike.label[zoom>=15][zoom<=16][amenity=police]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=police.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=police],
.citylike.label[zoom=14][amenity=police]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=police.png');
}

.building.label[zoom>=17][amenity=fire_station],
.citylike.label[zoom>=17][amenity=fire_station]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=fire_station.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=fire_station],
.citylike.label[zoom>=15][zoom<=16][amenity=fire_station]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=fire_station.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=fire_station],
.citylike.label[zoom=14][amenity=fire_station]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=fire_station.png');
}

.building.label[zoom>=17][amenity=hospital],
.citylike.label[zoom>=17][amenity=hospital]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=hospital.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=hospital],
.citylike.label[zoom>=15][zoom<=16][amenity=hospital]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=hospital.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=hospital],
.citylike.label[zoom=14][amenity=hospital]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=hospital.png');
}

.building.label[zoom>=17][amenity=parking],
.citylike.label[zoom>=17][amenity=parking]
{
    point-file: url('img/icons/16x16/panel/transport/amenity=parking.png');
}

.water.label[zoom>=16][size=large] name,
.parklike.label[zoom>=16][size=large] name,
.citylike.label[zoom>=16][size=large][amenity!=parking] name,
.building.label[zoom>=16][size=large] name,
.water.label[zoom>=17] name,
.parklike.label[zoom>=17] name,
.citylike.label[zoom>=17][amenity!=parking] name,
.building.label[zoom>=17] name
{
    text-wrap-width: 100;
    text-size: 12;
}

.water.label name
{
    text-halo-fill: #affcff;
}

.parklike.label name
{
    text-halo-fill: #d1ffb6;
}

.citylike.label[amenity!=parking] name
{
    text-halo-fill: #eeeeee;
}

.building.label name
{
    text-halo-fill: #dddddd;
}

Map
{
    map-bgcolor: #8cb6d3;
}

.coast.edge.outer
{
    line-width: 13;
    line-color: #a1cbea;
    line-join: round;
}

.coast.edge.inner
{
    line-width: 5;
    line-color: #7eaac1;
    line-join: round;
}

.coast.edge.outer[zoom<=12] { line-width: 9; }
.coast.edge.inner[zoom<=12] { line-width: 3; }

.water.area
{
    line-width: 2;
    line-color: #7eaac1;
    polygon-fill: #8cb6d3;
    line-join: round;
}

.water.line
{
    line-color: #7eaac1;
    line-join: round;
}

.water.line[zoom>=13],
.water.line[zoom>=15][waterway=stream]
{
    line-color: #8cb6d3;

    outline-width: 1;
    outline-color: #7eaac1;
    outline-join: round;
}

.water.line[zoom>=11][zoom<=12] { line-width: 2; }
.water.line[zoom>=11][zoom<=12][waterway=stream] { line-width: 1; }

.water.line[zoom=13] { line-width: 3; }
.water.line[zoom=13][waterway=stream] { line-width: 1; }

.water.line[zoom=14] { line-width: 5; }
.water.line[zoom=14][waterway=stream] { line-width: 2; }

.water.line[zoom=15] { line-width: 7; }
.water.line[zoom=15][waterway=stream] { line-width: 3; }

.water.line[zoom=16] { line-width: 9; }
.water.line[zoom=16][waterway=stream] { line-width: 5; }

.water.line[zoom>=17] { line-width: 12; }
.water.line[zoom>=17][waterway=stream] { line-width: 8; }

.coast.fill
{
    polygon-fill: #dceee9;
    /*
    line-width: 1;
    line-color: #dceee9;
    */
}

.citylike.area
{
    polygon-fill: #d0d0d0;
}

/*
.citylike.area[amenity=school],
.citylike.area[amenity=college],
.citylike.area[amenity=university]
{
    polygon-fill: #d2caba;
}
*/

.parklike.area
{
    polygon-fill: #91b156;
}

.parklike.area[zoom>=16][leisure!=pitch][leisure!=track],
.parklike.area[zoom>=14][zoom<=15][leisure!=pitch][leisure!=track][size=large]
{
    polygon-pattern-file: url('img/trees-z.png');
}

.parklike.area[zoom>=11]
{
    line-width: 1;
    line-color: #6dbe3c;
}

.parklike.area[landuse=cemetery]
{
    line-color: #799a67;
    polygon-fill: #94b580;
}

.parklike.area[zoom>=16][landuse=cemetery],
.parklike.area[zoom=15][landuse=cemetery][size=large]
{
    polygon-pattern-file: url('img/graveyard-z.png');
}

.building.area[zoom>=13]
{
    polygon-fill: #aaaaaa;
}

.building.area[zoom>=15]
{
    line-width: 1;
    line-color: #808080;
}

.water.label name,
.parklike.label name,
.citylike.label[amenity!=parking] name,
.building.label name
{
    text-face-name: "DejaVu Sans Book";
    text-fill: #000;
    text-placement: point;
    text-halo-radius: 2;
}

.water.label[zoom>=13][zoom<=15][size=large] name,
.parklike.label[zoom>=13][zoom<=15][size=large] name,
.citylike.label[zoom>=13][zoom<=15][size=large][amenity!=parking] name,
.building.label[zoom>=13][zoom<=15][size=large] name,
.water.label[zoom>=15][zoom<=16][size=medium] name,
.parklike.label[zoom>=15][zoom<=16][size=medium] name,
.citylike.label[zoom>=15][zoom<=16][size=medium][amenity!=parking] name,
.building.label[zoom>=15][zoom<=16][size=medium] name,
.water.label[zoom=16][size=small] name,
.parklike.label[zoom=16][size=small] name,
.citylike.label[zoom=16][size=small][amenity!=parking] name,
.building.label[zoom=16][size=small] name
{
    text-size: 9;
    text-wrap-width: 50;
}

.building.label[zoom>=17][amenity=school],
.citylike.label[zoom>=17][amenity=school]
{
    point-file: url('img/icons/24x24/symbol/landmark/amenity=school.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=school],
.citylike.label[zoom>=15][zoom<=16][amenity=school]
{
    point-file: url('img/icons/16x16/symbol/landmark/amenity=school.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=school],
.citylike.label[zoom=14][amenity=school]
{
    point-file: url('img/icons/12x12/symbol/landmark/amenity=school.png');
}

.building.label[zoom>=17][amenity=police],
.citylike.label[zoom>=17][amenity=police]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=police.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=police],
.citylike.label[zoom>=15][zoom<=16][amenity=police]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=police.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=police],
.citylike.label[zoom=14][amenity=police]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=police.png');
}

.building.label[zoom>=17][amenity=fire_station],
.citylike.label[zoom>=17][amenity=fire_station]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=fire_station.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=fire_station],
.citylike.label[zoom>=15][zoom<=16][amenity=fire_station]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=fire_station.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=fire_station],
.citylike.label[zoom=14][amenity=fire_station]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=fire_station.png');
}

.building.label[zoom>=17][amenity=hospital],
.citylike.label[zoom>=17][amenity=hospital]
{
    point-file: url('img/icons/24x24/symbol/emergency/amenity=hospital.png');
    text-dy: 20;
}

.building.label[zoom>=15][zoom<=16][amenity=hospital],
.citylike.label[zoom>=15][zoom<=16][amenity=hospital]
{
    point-file: url('img/icons/16x16/symbol/emergency/amenity=hospital.png');
    text-dy: 18;
}

.building.label[zoom=14][amenity=hospital],
.citylike.label[zoom=14][amenity=hospital]
{
    point-file: url('img/icons/12x12/symbol/emergency/amenity=hospital.png');
}

.building.label[zoom>=17][amenity=parking],
.citylike.label[zoom>=17][amenity=parking]
{
    point-file: url('img/icons/16x16/panel/transport/amenity=parking.png');
}

.water.label[zoom>=16][size=large] name,
.parklike.label[zoom>=16][size=large] name,
.citylike.label[zoom>=16][size=large][amenity!=parking] name,
.building.label[zoom>=16][size=large] name,
.water.label[zoom>=17] name,
.parklike.label[zoom>=17] name,
.citylike.label[zoom>=17][amenity!=parking] name,
.building.label[zoom>=17] name
{
    text-wrap-width: 100;
    text-size: 12;
}

.water.label name
{
    text-halo-fill: #affcff;
}

.parklike.label name
{
    text-halo-fill: #d1ffb6;
}

.citylike.label[amenity!=parking] name
{
    text-halo-fill: #eeeeee;
}

.building.label name
{
    text-halo-fill: #dddddd;
}