/// <summary> /// Constructs a run iterator over the given text from start /// (inclusive) to limit (exclusive). /// </summary> /// <param name="text"></param> /// <param name="start"></param> /// <param name="limit"></param> public ScriptRunIterator(IReplaceable text, int start, int limit) { this.text = text; this.textStart = start; this.textLimit = limit; this.Limit = start; }
/// <summary> /// Reset this iterator to point to a new string. This public /// method is used by classes that want to avoid allocating /// new <see cref="ReplaceableCharacterIterator"/> objects every /// time their <see cref="SetText(IReplaceable)"/> method /// is called. /// </summary> /// <param name="text">The <see cref="string"/> to be iterated over.</param> public void SetText(IReplaceable text) { this.text = text ?? throw new ArgumentNullException(nameof(text)); this.begin = 0; this.end = text.Length; this.pos = 0; }
/// <summary> /// Default implementation of <see cref="IUnicodeMatcher.Matches(IReplaceable, int[], int, bool)"/> for Unicode /// filters. Matches a single 16-bit code unit at offset. /// </summary> /// <stable>ICU 2.0</stable> public virtual MatchDegree Matches(IReplaceable text, int[] offset, int limit, bool incremental) { int c; if (offset[0] < limit && Contains(c = text.Char32At(offset[0]))) { offset[0] += UTF16.GetCharCount(c); return(MatchDegree.Match); } if (offset[0] > limit && Contains(text.Char32At(offset[0]))) { // Backup offset by 1, unless the preceding character is a // surrogate pair -- then backup by 2 (keep offset pointing at // the lead surrogate). --offset[0]; if (offset[0] >= 0) { offset[0] -= UTF16.GetCharCount(text.Char32At(offset[0])) - 1; } return(MatchDegree.Match); } if (incremental && offset[0] == limit) { return(MatchDegree.PartialMatch); } return(MatchDegree.Mismatch); }
/// <summary> /// <see cref="IUnicodeReplacer"/> API /// </summary> public virtual int Replace(IReplaceable text, int start, int limit, int[] cursor) { int outLen = 0; // Copy segment with out-of-band data int dest = limit; // If there was no match, that means that a quantifier // matched zero-length. E.g., x (a)* y matched "xy". if (matchStart >= 0) { if (matchStart != matchLimit) { text.Copy(matchStart, matchLimit, dest); outLen = matchLimit - matchStart; } } text.Replace(start, limit, ""); // delete original text return(outLen); }
public HtmlTemplate ReplaceTagsInTemplate(MerchantTribeApplication app, IReplaceable item, List <IReplaceable> repeatingItems) { List <IReplaceable> items = new List <IReplaceable>(); items.Add(item); return(ReplaceTagsInTemplate(app, items, repeatingItems)); }
private string GetDescription(IReplaceable instance) { if (instance == null) { return(string.Empty); } var result = ((ObjectInstance)instance).ToShortString(); if (instance is MoveableInstance) { result += " (" + instance.SecondaryAttribDesc + ": " + ((MoveableInstance)instance).Ocb + ")"; } else if (instance is StaticInstance && _editor.Level.Settings.GameVersion == TRVersion.Game.TRNG) { result += " (" + instance.SecondaryAttribDesc + ": " + ((StaticInstance)instance).Ocb + ")"; } else if (instance is SinkInstance) { result += " (" + instance.PrimaryAttribDesc + ": " + ((SinkInstance)instance).Strength + ")"; } else if (instance is ImportedGeometryInstance) { result += " (" + instance.SecondaryAttribDesc + ": " + ((ImportedGeometryInstance)instance).Scale.ToString(".0#") + ")"; } else if (instance is SoundSourceInstance) { result += " (" + instance.PrimaryAttribDesc + ": " + ((SoundSourceInstance)instance).SoundId + ")"; } return(result); }
public HtmlTemplate ReplaceTagsInTemplate(HccRequestContext context, IReplaceable item) { var items = new List <IReplaceable>(); items.Add(item); return(ReplaceTagsInTemplate(context, items)); }
public bool ReplaceableEquals(IReplaceable other, bool withProperties = false) { var otherInstance = other as ItemInstance; return(otherInstance?.ItemType.IsStatic == ItemType.IsStatic && otherInstance.ItemType == ItemType && (withProperties ? otherInstance?.Ocb == Ocb : true)); }
/// <summary> /// Set the text for iteration. /// </summary> /// <param name="rep"><see cref="IReplaceable"/> to iterate over.</param> public virtual void SetText(IReplaceable rep) { this.rep = rep; limit = contextLimit = rep.Length; cpStart = cpLimit = index = contextStart = 0; dir = 0; reachedLimit = false; }
/// <summary> /// Set the text for iteration. /// </summary> /// <param name="rep"><see cref="IReplaceable"/> to iterate over.</param> public virtual void SetText(IReplaceable rep) { this.rep = rep; limit = contextLimit = rep.Length; cpStart = cpLimit = index = contextStart = 0; forward = true; reachedLimit = false; Current = -1; }
// public constructor ------------------------------------------------------ /// <summary> /// Public constructor. /// </summary> /// <param name="replaceable">Text which the iterator will be based on.</param> public ReplaceableUCharacterIterator(IReplaceable replaceable) { if (replaceable == null) { throw new ArgumentException(); } this.replaceable = replaceable; this.currentIndex = 0; }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/>. /// </summary> /// <param name="text"></param> /// <param name="index"></param> /// <param name="incremental"></param> protected override void HandleTransliterate(IReplaceable text, TransliterationPosition index, bool incremental) { // Our caller (filteredTransliterate) has already narrowed us // to an unfiltered run. Delete it. text.Replace(index.Start, index.Limit, ""); int len = index.Limit - index.Start; index.ContextLimit -= len; index.Limit -= len; }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>. /// </summary> protected override void HandleTransliterate(IReplaceable text, Position pos, bool isIncremental) { int allStart = pos.Start; int allLimit = pos.Limit; ScriptRunIterator it = new ScriptRunIterator(text, pos.ContextStart, pos.ContextLimit); while (it.Next()) { // Ignore runs in the ante context if (it.Limit <= allStart) { continue; } // Try to instantiate transliterator from it.scriptCode to // our target or target/variant Transliterator t = GetTransliterator(it.ScriptCode); if (t == null) { // We have no transliterator. Do nothing, but keep // pos.start up to date. pos.Start = it.Limit; continue; } // If the run end is before the transliteration limit, do // a non-incremental transliteration. Otherwise do an // incremental one. bool incremental = isIncremental && (it.Limit >= allLimit); pos.Start = Math.Max(allStart, it.Start); pos.Limit = Math.Min(allLimit, it.Limit); int limit = pos.Limit; t.FilteredTransliterate(text, pos, incremental); int delta = pos.Limit - limit; allLimit += delta; it.AdjustLimit(delta); // We're done if we enter the post context if (it.Limit >= allLimit) { break; } } // Restore limit. pos.start is fine where the last transliterator // left it, or at the end of the last run. pos.Limit = allLimit; }
/// <summary> /// Retrieves the message of the given Message code and replaces all ReplacementCodes with the proper value /// </summary> /// <param name="text">The text to parse</param> /// <param name="replaceable">Any objects that are available should be passed on as they may be used as part of the parsing process.</param> /// <returns>The text element parsed</returns> public string ParseMessage(string text, IReplaceable <TKey> replaceable) { if (string.IsNullOrWhiteSpace(text)) { return(string.Empty); } StringBuilder message = new StringBuilder(); List <IReplaceableCode <TKey> > codes = replaceable.GetReplaceableCodes(); Dictionary <TKey, object> objectsToParse = replaceable.GetReplaceables(); return(this.ParseText(text, codes, objectsToParse)); }
public bool Replace(IReplaceable other, bool withProperties) { var thatSink = (SinkInstance)other; if (!ReplaceableEquals(other) && Strength != thatSink?.Strength) { Strength = thatSink.Strength; return(true); } else { return(false); } }
public bool Replace(IReplaceable other, bool withProperties) { var thatSound = (SoundSourceInstance)other; if (!ReplaceableEquals(other) && thatSound.SoundId != SoundId) { SoundId = ((SoundSourceInstance)other).SoundId; return(true); } else { return(false); } }
public bool Replace(IReplaceable other, bool withProperties) { var thatColor = (LightInstance)other; if (!ReplaceableEquals(other) && Color != thatColor?.Color) { Color = thatColor.Color; return(true); } else { return(false); } }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>. /// </summary> protected override void HandleTransliterate(IReplaceable text, Position pos, bool incremental) { int start = pos.Start; int limit = pos.Limit; StringBuilder buf = new StringBuilder(prefix); int prefixLen = prefix.Length; bool redoPrefix = false; while (start < limit) { int c = grokSupplementals ? text.Char32At(start) : text[start]; int charLen = grokSupplementals ? UTF16.GetCharCount(c) : 1; if ((c & 0xFFFF0000) != 0 && supplementalHandler != null) { buf.Length = 0; buf.Append(supplementalHandler.prefix); Utility.AppendNumber(buf, c, supplementalHandler.radix, supplementalHandler.minDigits); buf.Append(supplementalHandler.suffix); redoPrefix = true; } else { if (redoPrefix) { buf.Length = 0; buf.Append(prefix); redoPrefix = false; } else { buf.Length = prefixLen; } Utility.AppendNumber(buf, c, radix, minDigits); buf.Append(suffix); } text.Replace(start, start + charLen, buf.ToString()); start += buf.Length; limit += buf.Length - charLen; } pos.ContextLimit += limit - pos.Limit; pos.Limit = limit; pos.Start = start; }
/// <summary> /// <see cref="IUnicodeReplacer"/> API /// </summary> public virtual int Replace(IReplaceable text, int start, int limit, int[] cursor) { // First delegate to subordinate replacer int len = replacer.Replace(text, start, limit, cursor); limit = start + len; // Now transliterate limit = translit.Transliterate(text, start, limit); return(limit - start); }
/// <summary> /// Transliterate the given text with the given UTransPosition /// indices. Return TRUE if the transliteration should continue /// or FALSE if it should halt (because of a U_PARTIAL_MATCH match). /// Note that FALSE is only ever returned if isIncremental is TRUE. /// </summary> /// <param name="text">The text to be transliterated.</param> /// <param name="pos">The position indices, which will be updated.</param> /// <param name="incremental">If TRUE, assume new text may be inserted /// at index.Limit, and return FALSE if thre is a partial match.</param> /// <returns>TRUE unless a U_PARTIAL_MATCH has been obtained, /// indicating that transliteration should stop until more text /// arrives.</returns> public virtual bool Transliterate(IReplaceable text, TransliterationPosition pos, bool incremental) { int indexByte = text.Char32At(pos.Start) & 0xFF; for (int i = index[indexByte]; i < index[indexByte + 1]; ++i) { MatchDegree m = rules[i].MatchAndReplace(text, pos, incremental); switch (m) { case MatchDegree.Match: if (Transliterator.DEBUG) { Console.Out.WriteLine((incremental ? "Rule.i: match " : "Rule: match ") + rules[i].ToRule(true) + " => " + UtilityExtensions.FormatInput(text, pos)); } return(true); case MatchDegree.PartialMatch: if (Transliterator.DEBUG) { Console.Out.WriteLine((incremental ? "Rule.i: partial match " : "Rule: partial match ") + rules[i].ToRule(true) + " => " + UtilityExtensions.FormatInput(text, pos)); } return(false); default: if (Transliterator.DEBUG) { Console.Out.WriteLine("Rule: no match " + rules[i]); } break; } } // No match or partial match from any rule pos.Start += UTF16.GetCharCount(text.Char32At(pos.Start)); if (Transliterator.DEBUG) { Console.Out.WriteLine((incremental ? "Rule.i: no match => " : "Rule: no match => ") + UtilityExtensions.FormatInput(text, pos)); } return(true); }
#pragma warning disable 809 protected override void HandleTransliterate(IReplaceable text, TransliterationPosition index, bool incremental) #pragma warning disable 809 { /* We keep start and limit fixed the entire time, * relative to the text -- limit may move numerically if text is * inserted or removed. The cursor moves from start to limit, with * replacements happening under it. * * Example: rules 1. ab>x|y * 2. yc>z * * |eabcd start - no match, advance cursor * e|abcd match rule 1 - change text & adjust cursor * ex|ycd match rule 2 - change text & adjust cursor * exz|d no match, advance cursor * exzd| done */ /* A rule like * a>b|a * creates an infinite loop. To prevent that, we put an arbitrary * limit on the number of iterations that we take, one that is * high enough that any reasonable rules are ok, but low enough to * prevent a server from hanging. The limit is 16 times the * number of characters n, unless n is so large that 16n exceeds a * uint32_t. */ lock (data) { int loopCount = 0; int loopLimit = (index.Limit - index.Start) << 4; if (loopLimit < 0) { loopLimit = 0x7FFFFFFF; } while (index.Start < index.Limit && loopCount <= loopLimit && data.RuleSet.Transliterate(text, index, incremental)) { ++loopCount; } } }
///// <summary> ///// Constructs an iterator with an initial index of 0. ///// </summary> ///// <param name="text">The <see cref="string"/> to be iterated over.</param> //public ReplaceableCharacterIterator(IReplaceable text) // : this(text, 0) //{ //} ///// <summary> ///// Constructs an iterator with the specified initial index. ///// </summary> ///// <param name="text">The <see cref="string"/> to be iterated over.</param> ///// <param name="pos">Initial iterator position.</param> //public ReplaceableCharacterIterator(IReplaceable text, int pos) // : this(text, 0, text.Length, pos) //{ //} /// <summary> /// Constructs an iterator over the given range of the given string, with the /// index set at the specified position. /// </summary> /// <param name="text">The <see cref="string"/> to be iterated over.</param> /// <param name="begin">Index of the first character.</param> /// <param name="end">Index of the character following the last character.</param> /// <param name="pos">Initial iterator position.</param> public ReplaceableCharacterIterator(IReplaceable text, int begin, int end, int pos) { this.text = text ?? throw new ArgumentNullException(nameof(text)); if (begin < 0 || begin > end || end > text.Length) { throw new ArgumentException("Invalid substring range"); } if (pos < begin || pos > end) { throw new ArgumentException("Invalid position"); } this.begin = begin; this.end = end; this.pos = pos; }
/// <summary> /// Implement <see cref="IUnicodeMatcher"/> API. /// </summary> public virtual MatchDegree Matches(IReplaceable text, int[] offset, int limit, bool incremental) { int start = offset[0]; int count = 0; while (count < maxCount) { int pos = offset[0]; MatchDegree m = matcher.Matches(text, offset, limit, incremental); if (m == MatchDegree.Match) { ++count; if (pos == offset[0]) { // If offset has not moved we have a zero-width match. // Don't keep matching it infinitely. break; } } else if (incremental && m == MatchDegree.PartialMatch) { return(MatchDegree.PartialMatch); } else { break; } } if (incremental && offset[0] == limit) { return(MatchDegree.PartialMatch); } if (count >= minCount) { return(MatchDegree.Match); } offset[0] = start; return(MatchDegree.Mismatch); }
public bool Replace(IReplaceable other, bool withProperties) { var result = false; if (!ReplaceableEquals(other)) { if (ItemType.IsStatic) { var thisObj = (StaticInstance)this; var thatObj = (StaticInstance)other; if (thisObj.WadObjectId != thatObj.WadObjectId) { thisObj.WadObjectId = thatObj.WadObjectId; result = true; } if (withProperties && thisObj.Ocb != thatObj.Ocb) { thisObj.Ocb = thatObj.Ocb; result = true; } } else { var thisObj = (MoveableInstance)this; var thatObj = (MoveableInstance)other; if (thisObj.WadObjectId != thatObj.WadObjectId) { thisObj.WadObjectId = thatObj.WadObjectId; result = true; } if (withProperties && thisObj.Ocb != thatObj.Ocb) { thisObj.Ocb = thatObj.Ocb; result = true; } } } return(result); }
public bool Replace(IReplaceable other, bool withProperties) { var result = false; if (!ReplaceableEquals(other)) { var thatObj = (ImportedGeometryInstance)other; if (Model != thatObj.Model) { Model = thatObj.Model; result = true; } if (withProperties && Scale != thatObj.Scale) { Scale = thatObj.Scale; result = true; } } return(result); }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>. /// </summary> protected override void HandleTransliterate(IReplaceable text, Position offsets, bool isIncremental) { int cursor = offsets.Start; int limit = offsets.Limit; StringBuilder str = new StringBuilder(); str.Append(OPEN_DELIM); int len; string name; while (cursor < limit) { int c = text.Char32At(cursor); if ((name = UCharacter.GetExtendedName(c)) != null) { str.Length = OPEN_DELIM_LEN; str.Append(name).Append(CLOSE_DELIM); int clen = UTF16.GetCharCount(c); text.Replace(cursor, cursor + clen, str.ToString()); len = str.Length; cursor += len; // advance cursor by 1 and adjust for new text limit += len - clen; // change in length } else { ++cursor; } } offsets.ContextLimit += limit - offsets.Limit; offsets.Limit = limit; offsets.Start = cursor; }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/>. /// </summary> protected override void HandleTransliterate(IReplaceable text, TransliterationPosition offsets, bool isIncremental) { // start and limit of the input range int start = offsets.Start; int limit = offsets.Limit; if (start >= limit) { return; } /* * Normalize as short chunks at a time as possible even in * bulk mode, so that styled text is minimally disrupted. * In incremental mode, a chunk that ends with offsets.limit * must not be normalized. * * If it was known that the input text is not styled, then * a bulk mode normalization could be used. * (For details, see the comment in the C++ version.) */ StringBuilder segment = new StringBuilder(); StringBuilder normalized = new StringBuilder(); int c = text.Char32At(start); do { int prev = start; // Skip at least one character so we make progress. // c holds the character at start. segment.Length = 0; do { segment.AppendCodePoint(c); start += Character.CharCount(c); } while (start < limit && !norm2.HasBoundaryBefore(c = text.Char32At(start))); if (start == limit && isIncremental && !norm2.HasBoundaryAfter(c)) { // stop in incremental mode when we reach the input limit // in case there are additional characters that could change the // normalization result start = prev; break; } norm2.Normalize(segment, normalized); if (!UTF16Plus.Equal(segment, normalized)) { // replace the input chunk with its normalized form text.Replace(prev, start - prev, normalized.ToString()); // ICU4N: Corrected 2nd parameter // update all necessary indexes accordingly int delta = normalized.Length - (start - prev); start += delta; limit += delta; } } while (start < limit); offsets.Start = start; offsets.ContextLimit += limit - offsets.Limit; offsets.Limit = limit; }
//= public static UnicodeReplacer valueOf(String output, //= int cursorPos, //= RuleBasedTransliterator.Data data) { //= if (output.length() == 1) { //= char c = output.charAt(0); //= UnicodeReplacer r = data.lookupReplacer(c); //= if (r != null) { //= return r; //= } //= } //= return new StringReplacer(output, cursorPos, data); //= } /// <summary> /// <see cref="IUnicodeReplacer"/> API /// </summary> public virtual int Replace(IReplaceable text, int start, int limit, int[] cursor) { int outLen; int newStart = 0; // NOTE: It should be possible to _always_ run the complex // processing code; just slower. If not, then there is a bug // in the complex processing code. // Simple (no nested replacers) Processing Code : if (!isComplex) { text.Replace(start, limit, output); outLen = output.Length; // Setup default cursor position (for cursorPos within output) newStart = cursorPos; } // Complex (nested replacers) Processing Code : else { /* When there are segments to be copied, use the Replaceable.copy() * API in order to retain out-of-band data. Copy everything to the * end of the string, then copy them back over the key. This preserves * the integrity of indices into the key and surrounding context while * generating the output text. */ StringBuffer buf = new StringBuffer(); int oOutput; // offset into 'output' isComplex = false; // The temporary buffer starts at tempStart, and extends // to destLimit + tempExtra. The start of the buffer has a single // character from before the key. This provides style // data when addition characters are filled into the // temporary buffer. If there is nothing to the left, use // the non-character U+FFFF, which Replaceable subclasses // should treat specially as a "no-style character." // destStart points to the point after the style context // character, so it is tempStart+1 or tempStart+2. int tempStart = text.Length; // start of temp buffer int destStart = tempStart; // copy new text to here if (start > 0) { int len = UTF16.GetCharCount(text.Char32At(start - 1)); text.Copy(start - len, start, tempStart); destStart += len; } else { text.Replace(tempStart, tempStart, "\uFFFF"); destStart++; } int destLimit = destStart; int tempExtra = 0; // temp chars after destLimit for (oOutput = 0; oOutput < output.Length;) { if (oOutput == cursorPos) { // Record the position of the cursor newStart = buf.Length + destLimit - destStart; // relative to start // the buf.length() was inserted for bug 5789 // the problem is that if we are accumulating into a buffer (when r == null below) // then the actual length of the text at that point needs to add the buf length. // there was an alternative suggested in #5789, but that looks like it won't work // if we have accumulated some stuff in the dest part AND have a non-zero buffer. } int c = UTF16.CharAt(output, oOutput); // When we are at the last position copy the right style // context character into the temporary buffer. We don't // do this before because it will provide an incorrect // right context for previous replace() operations. int nextIndex = oOutput + UTF16.GetCharCount(c); if (nextIndex == output.Length) { tempExtra = UTF16.GetCharCount(text.Char32At(limit)); text.Copy(limit, limit + tempExtra, destLimit); } IUnicodeReplacer r = data.LookupReplacer(c); if (r == null) { // Accumulate straight (non-segment) text. UTF16.Append(buf, c); } else { isComplex = true; // Insert any accumulated straight text. if (buf.Length > 0) { text.Replace(destLimit, destLimit, buf.ToString()); destLimit += buf.Length; buf.Length = 0; } // Delegate output generation to replacer object int len = r.Replace(text, destLimit, destLimit, cursor); destLimit += len; } oOutput = nextIndex; } // Insert any accumulated straight text. if (buf.Length > 0) { text.Replace(destLimit, destLimit, buf.ToString()); destLimit += buf.Length; } if (oOutput == cursorPos) { // Record the position of the cursor newStart = destLimit - destStart; // relative to start } outLen = destLimit - destStart; // Copy new text to start, and delete it text.Copy(destStart, destLimit, start); text.Replace(tempStart + outLen, destLimit + tempExtra + outLen, ""); // Delete the old text (the key) text.Replace(start + outLen, limit + outLen, ""); } if (hasCursor) { // Adjust the cursor for positions outside the key. These // refer to code points rather than code units. If cursorPos // is within the output string, then use newStart, which has // already been set above. if (cursorPos < 0) { newStart = start; int n = cursorPos; // Outside the output string, cursorPos counts code points while (n < 0 && newStart > 0) { newStart -= UTF16.GetCharCount(text.Char32At(newStart - 1)); ++n; } newStart += n; } else if (cursorPos > output.Length) { newStart = start + outLen; int n = cursorPos - output.Length; // Outside the output string, cursorPos counts code points while (n > 0 && newStart < text.Length) { newStart += UTF16.GetCharCount(text.Char32At(newStart)); --n; } newStart += n; } else { // Cursor is within output string. It has been set up above // to be relative to start. newStart += start; } cursor[0] = newStart; } return(outLen); }
/// <summary> /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/> /// </summary> protected override void HandleTransliterate(IReplaceable text, TransliterationPosition offsets, bool isIncremental) { lock (syncLock) { if (csp == null) { return; } if (offsets.Start >= offsets.Limit) { return; } iter.SetText(text); result.Length = 0; int c, delta; // Walk through original string // If there is a case change, modify corresponding position in replaceable iter.SetIndex(offsets.Start); iter.SetLimit(offsets.Limit); iter.SetContextLimits(offsets.ContextStart, offsets.ContextLimit); while ((c = iter.NextCaseMapCP()) >= 0) { c = csp.ToFullFolding(c, result, 0); // toFullFolding(int c, StringBuffer out, int options) if (iter.DidReachLimit && isIncremental) { // the case mapping function tried to look beyond the context limit // wait for more input offsets.Start = iter.CaseMapCPStart; return; } /* decode the result */ if (c < 0) { /* c mapped to itself, no change */ continue; } else if (c <= UCaseProperties.MaxStringLength) { /* replace by the mapping string */ delta = iter.Replace(result.ToString()); result.Length = 0; } else { /* replace by single-code point mapping */ delta = iter.Replace(UTF16.ValueOf(c)); } if (delta != 0) { offsets.Limit += delta; offsets.ContextLimit += delta; } } offsets.Start = offsets.Limit; } }
/// <summary> /// Implement <see cref="IUnicodeMatcher"/> /// </summary> public virtual MatchDegree Matches(IReplaceable text, int[] offset, int limit, bool incremental) { // Note (1): We process text in 16-bit code units, rather than // 32-bit code points. This works because stand-ins are // always in the BMP and because we are doing a literal match // operation, which can be done 16-bits at a time. int i; int[] cursor = new int[] { offset[0] }; if (limit < cursor[0]) { // Match in the reverse direction for (i = pattern.Length - 1; i >= 0; --i) { char keyChar = pattern[i]; // OK; see note (1) above IUnicodeMatcher subm = data.LookupMatcher(keyChar); if (subm == null) { if (cursor[0] > limit && keyChar == text[cursor[0]]) { // OK; see note (1) above --cursor[0]; } else { return(MatchDegree.Mismatch); } } else { MatchDegree m = subm.Matches(text, cursor, limit, incremental); if (m != MatchDegree.Match) { return(m); } } } // Record the match position, but adjust for a normal // forward start, limit, and only if a prior match does not // exist -- we want the rightmost match. if (matchStart < 0) { matchStart = cursor[0] + 1; matchLimit = offset[0] + 1; } } else { for (i = 0; i < pattern.Length; ++i) { if (incremental && cursor[0] == limit) { // We've reached the context limit without a mismatch and // without completing our match. return(MatchDegree.PartialMatch); } char keyChar = pattern[i]; // OK; see note (1) above IUnicodeMatcher subm = data.LookupMatcher(keyChar); if (subm == null) { // Don't need the cursor < limit check if // incremental is true (because it's done above); do need // it otherwise. if (cursor[0] < limit && keyChar == text[cursor[0]]) { // OK; see note (1) above ++cursor[0]; } else { return(MatchDegree.Mismatch); } } else { MatchDegree m = subm.Matches(text, cursor, limit, incremental); if (m != MatchDegree.Match) { return(m); } } } // Record the match position matchStart = offset[0]; matchLimit = cursor[0]; } offset[0] = cursor[0]; return(MatchDegree.Match); }
public HtmlTemplate ReplaceTagsInTemplate(MerchantTribeApplication app, IReplaceable item, List<IReplaceable> repeatingItems) { List<IReplaceable> items = new List<IReplaceable>(); items.Add(item); return ReplaceTagsInTemplate(app, items, repeatingItems); }