Пример #1
0
        /// <summary>
        /// Parses a tag's contents into data.
        /// </summary>
        static public void Parse(StringSlice inSlice, IDelimiterRules inDelimiters, out TagData outTagData)
        {
            if (inDelimiters == null)
            {
                throw new ArgumentNullException("inDelimiters");
            }

            StringSlice tag = inSlice;

            tag = tag.Trim(MinimalWhitespaceChars);

            bool bRemovedTagBoundaries = false;

            if (tag.StartsWith(inDelimiters.TagStartDelimiter))
            {
                tag = tag.Substring(inDelimiters.TagStartDelimiter.Length);
                bRemovedTagBoundaries = true;
            }
            if (tag.EndsWith(inDelimiters.TagEndDelimiter))
            {
                tag = tag.Substring(0, tag.Length - inDelimiters.TagEndDelimiter.Length);
                bRemovedTagBoundaries = true;
            }

            if (bRemovedTagBoundaries)
            {
                tag = tag.Trim(MinimalWhitespaceChars);
            }

            if (inSlice.Length == 0)
            {
                outTagData = default(TagData);
                return;
            }

            ClosingTagState closeState = 0;

            char endDelim = inDelimiters.RegionCloseDelimiter;

            if (endDelim != 0)
            {
                if (tag.StartsWith(endDelim))
                {
                    closeState |= ClosingTagState.Start;
                    tag         = tag.Substring(1);
                }
                if (tag.EndsWith(endDelim))
                {
                    closeState |= ClosingTagState.End;
                    tag         = tag.Substring(0, tag.Length - 1);
                }
            }

            if (closeState != 0)
            {
                tag = tag.Trim(MinimalWhitespaceChars);
            }

            char[] dataDelims   = inDelimiters.TagDataDelimiters;
            int    dataDelimIdx = tag.Length;

            foreach (var delim in dataDelims)
            {
                int idx = tag.IndexOf(delim);
                if (idx >= 0 && idx < dataDelimIdx)
                {
                    dataDelimIdx = idx;
                    if (idx <= 0)
                    {
                        break;
                    }
                }
            }

            if (dataDelimIdx >= tag.Length)
            {
                outTagData.Id   = tag;
                outTagData.Data = StringSlice.Empty;
            }
            else
            {
                outTagData.Id   = tag.Substring(0, dataDelimIdx).TrimEnd(MinimalWhitespaceChars);
                outTagData.Data = tag.Substring(dataDelimIdx).TrimStart(dataDelims).TrimStart(MinimalWhitespaceChars);
            }

            outTagData.m_CloseState = closeState;
        }
Пример #2
0
        /// <summary>
        /// Returns if the given string contains any text or rich text tags.
        /// </summary>
        static public bool ContainsText(StringSlice inString, IDelimiterRules inDelimiters, IEnumerable <string> inTextTags = null)
        {
            bool bTrackRichText = inDelimiters.RichText;
            bool bTrackTags     = !bTrackRichText || !HasSameDelims(inDelimiters, RichTextDelimiters);

            int length    = inString.Length;
            int charIdx   = 0;
            int richStart = -1;
            int tagStart  = -1;
            int copyStart = 0;

            while (charIdx < length)
            {
                if (bTrackRichText)
                {
                    if (inString.AttemptMatch(charIdx, "<"))
                    {
                        richStart = charIdx;
                    }
                    else if (inString.AttemptMatch(charIdx, ">"))
                    {
                        return(true);
                    }
                }

                if (bTrackTags)
                {
                    if (inString.AttemptMatch(charIdx, inDelimiters.TagStartDelimiter))
                    {
                        tagStart = charIdx;
                    }
                    else if (inString.AttemptMatch(charIdx, inDelimiters.TagEndDelimiter))
                    {
                        StringSlice check = inString.Substring(copyStart, tagStart - copyStart);
                        if (!check.IsWhitespace)
                        {
                            return(true);
                        }

                        if (inTextTags != null)
                        {
                            TagData data = TagData.Parse(inString.Substring(tagStart, charIdx - tagStart + 1), inDelimiters);
                            foreach (var tag in inTextTags)
                            {
                                if (data.Id == tag)
                                {
                                    return(true);
                                }
                            }
                        }

                        copyStart = charIdx + 1;
                        tagStart  = -1;
                        richStart = -1;
                    }
                }

                ++charIdx;
            }

            StringSlice finalCheck = inString.Substring(copyStart, length - copyStart);

            return(!finalCheck.IsWhitespace);
        }
Пример #3
0
            internal bool Evaluate(TagData inData, object inContext, out TagEventData outEvent)
            {
                outEvent           = new TagEventData(m_EventId);
                outEvent.IsClosing = inData.IsClosing();

                switch (m_DataMode)
                {
                case DataMode.String:
                {
                    if (inData.Data.IsEmpty)
                    {
                        outEvent.StringArgument = m_DefaultString;
                    }
                    else
                    {
                        outEvent.StringArgument = inData.Data;
                    }
                    break;
                }

                case DataMode.Float:
                {
                    float arg;
                    if (!StringParser.TryParseFloat(inData.Data, out arg))
                    {
                        arg = m_DefaultValue.AsFloat();
                    }
                    outEvent.Argument0 = arg;
                    break;
                }

                case DataMode.Bool:
                {
                    bool arg;
                    if (!StringParser.TryParseBool(inData.Data, out arg))
                    {
                        arg = m_DefaultValue.AsBool();
                    }
                    outEvent.Argument0 = arg;
                    break;
                }

                case DataMode.StringHash:
                {
                    StringHash32 arg;
                    if (!StringHash32.TryParse(inData.Data, out arg))
                    {
                        arg = m_DefaultValue.AsStringHash();
                    }
                    outEvent.Argument0 = arg;
                    break;
                }
                }

                if (m_HandleClosing && outEvent.IsClosing)
                {
                    outEvent.Type = m_EventClosingId;
                    if (m_EventClosingDelegate != null)
                    {
                        m_EventClosingDelegate(inData, inContext, ref outEvent);
                    }

                    return(true);
                }
                else
                {
                    if (m_EventDelegate != null)
                    {
                        m_EventDelegate(inData, inContext, ref outEvent);
                    }

                    return(true);
                }
            }
Пример #4
0
        protected void ProcessInput(StringSlice inInput, TagString outTarget, object inContext, out bool outbModified)
        {
            bool bModified      = false;
            bool bTrackRichText = m_Delimiters.RichText;
            bool bTrackTags     = !bTrackRichText || !HasSameDelims(m_Delimiters, RichTextDelimiters);
            bool bIsCurlyBrace  = HasSameDelims(m_Delimiters, CurlyBraceDelimiters);

            if (!bTrackRichText && m_EventProcessor == null && m_ReplaceProcessor == null)
            {
                // if we're not considering rich text, and we have no processors, there's nothing to do here
                outTarget.AddNode(TagNodeData.TextNode((uint)inInput.Length));
                outbModified = false;
                return;
            }

            ParseState state = new ParseState();

            state.Initialize(inInput, outTarget, inContext, m_RichBuilder, m_StrippedBuilder, m_SpliceBuilder);

            int length  = state.Input.Length;
            int charIdx = 0;

            while (charIdx < length)
            {
                bool bHandled = false;

                if (bTrackRichText)
                {
                    if (state.Input.AttemptMatch(charIdx, "<"))
                    {
                        state.RichStart = charIdx;
                    }
                    else if (state.RichStart >= 0 && state.Input.AttemptMatch(charIdx, ">"))
                    {
                        StringSlice richSlice = state.Input.Substring(state.RichStart + 1, charIdx - state.RichStart - 1);
                        TagData     richTag   = TagData.Parse(richSlice, RichTextDelimiters);

                        CopyNonRichText(ref state, state.RichStart);

                        bool bRichHandled = false;

                        if (RecognizeRichText(richTag, m_Delimiters))
                        {
                            CopyRichTag(ref state, charIdx + 1);
                            if (StringUtils.RichText.GeneratesVisibleCharacter(richTag.Id.ToString()))
                            {
                                CopyOnlyNonRichText(ref state, VisibleRichTagChar);
                            }
                            bRichHandled = true;
                        }
                        else if (!bTrackTags)
                        {
                            if (m_ReplaceProcessor != null)
                            {
                                string replace;
                                if (m_ReplaceProcessor.TryReplace(richTag, richSlice, state.Context, out replace))
                                {
                                    if (ContainsPotentialTags(replace, m_Delimiters))
                                    {
                                        RestartString(ref state, replace, charIdx + 1);
                                        charIdx = -1;
                                        length  = state.Input.Length;
                                    }
                                    else
                                    {
                                        SkipText(ref state, charIdx + 1);
                                        AddNonRichText(ref state, replace);
                                    }
                                    bRichHandled = true;
                                }
                            }

                            if (!bRichHandled && m_EventProcessor != null)
                            {
                                TagEventData eventData;
                                if (m_EventProcessor.TryProcess(richTag, state.Context, out eventData))
                                {
                                    outTarget.AddEvent(eventData);
                                    SkipText(ref state, charIdx + 1);
                                    bRichHandled = true;
                                }
                            }
                        }

                        if (!bRichHandled)
                        {
                            Debug.LogWarningFormat("[TagStringParser] Unrecognized text tag '{0}' in source '{1}'", richSlice, inInput);
                            CopyNonRichText(ref state, charIdx + 1);
                        }
                        else
                        {
                            bModified = true;
                        }

                        state.RichStart = -1;
                        state.TagStart  = -1;
                        bHandled        = true;
                    }
                }

                if (!bHandled && bTrackTags)
                {
                    if (state.Input.AttemptMatch(charIdx, m_Delimiters.TagStartDelimiter))
                    {
                        state.TagStart = charIdx;
                    }
                    else if (state.TagStart >= 0 && state.Input.AttemptMatch(charIdx, m_Delimiters.TagEndDelimiter))
                    {
                        StringSlice tagSlice = state.Input.Substring(state.TagStart + m_Delimiters.TagStartDelimiter.Length, charIdx - state.TagStart + 1 - m_Delimiters.TagEndDelimiter.Length - m_Delimiters.TagStartDelimiter.Length);
                        TagData     tag      = TagData.Parse(tagSlice, m_Delimiters);

                        CopyNonRichText(ref state, state.TagStart);

                        bool bTagHandled = false;

                        if (bIsCurlyBrace && tag.Data.IsEmpty)
                        {
                            int argIndex;
                            if (StringParser.TryParseInt(tag.Id, out argIndex))
                            {
                                CopyNonRichText(ref state, charIdx + 1);
                                bTagHandled = true;
                            }
                        }

                        if (!bTagHandled && m_ReplaceProcessor != null)
                        {
                            string replace;
                            if (m_ReplaceProcessor.TryReplace(tag, tagSlice, state.Context, out replace))
                            {
                                if (ContainsPotentialTags(replace, m_Delimiters))
                                {
                                    RestartString(ref state, replace, charIdx + 1);
                                    charIdx = -1;
                                    length  = state.Input.Length;
                                }
                                else
                                {
                                    SkipText(ref state, charIdx + 1);
                                    AddNonRichText(ref state, replace);
                                }
                                bTagHandled = true;
                            }
                        }

                        if (!bTagHandled && m_EventProcessor != null)
                        {
                            TagEventData eventData;
                            if (m_EventProcessor.TryProcess(tag, state.Context, out eventData))
                            {
                                outTarget.AddEvent(eventData);
                                SkipText(ref state, charIdx + 1);
                                bTagHandled = true;
                            }
                        }

                        if (!bTagHandled)
                        {
                            Debug.LogWarningFormat("[TagStringParser] Unrecognized text tag '{0}' in source '{1}'", tagSlice, inInput);
                            CopyNonRichText(ref state, charIdx + 1);
                        }
                        else
                        {
                            bModified = true;
                        }

                        state.TagStart  = -1;
                        state.RichStart = -1;
                        bHandled        = true;
                    }
                }

                if (!bHandled && state.TagStart == -1 && state.RichStart == -1 && m_ReplaceProcessor != null)
                {
                    string charCodeReplace;
                    if (m_ReplaceProcessor.TryReplace(state.Input[charIdx], inContext, out charCodeReplace))
                    {
                        CopyNonRichText(ref state, charIdx);
                        if (ContainsPotentialTags(charCodeReplace, m_Delimiters))
                        {
                            RestartString(ref state, charCodeReplace, charIdx + 1);
                            charIdx = -1;
                            length  = state.Input.Length;
                        }
                        else
                        {
                            SkipText(ref state, charIdx + 1);
                            AddNonRichText(ref state, charCodeReplace);
                        }
                    }
                }

                ++charIdx;
            }

            CopyNonRichText(ref state, length);
            outbModified = bModified;
        }