static public void CanTrimEnd() { StringSlice firstString = "Trim Me \r"; StringSlice trimmed = firstString.TrimEnd(); Assert.AreEqual("Trim Me", trimmed.ToString()); }
public void It_Can_Render_LiteralTags() { StringSlice content = new StringSlice("I'm a literal tag"); var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var rawTokenRenderer = new LiteralTokenRenderer(); rawTokenRenderer.Write( stringRenderer, new LiteralToken() { Content = new[] { content } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(content.ToString(), myStr); }
static public void CanTrimBoth() { StringSlice firstString = "\n \tTrim Me\t\n"; StringSlice trimmed = firstString.Trim(); Assert.AreEqual("Trim Me", trimmed.ToString()); }
private bool TryParseCheckCompoundPatternIntoCompoundPatterns(string parameterText, List <PatternEntry> entries) { var parameters = parameterText.SliceOnTabOrSpace(); if (parameters.Length == 0) { Builder.LogWarning("Failed to parse compound pattern from: " + parameterText); return(false); } var pattern = parameters[0]; StringSlice pattern2 = StringSlice.Null; StringSlice pattern3 = StringSlice.Null; var condition = default(FlagValue); var condition2 = default(FlagValue); var slashIndex = pattern.IndexOf('/'); if (slashIndex >= 0) { if (!TryParseFlag(pattern.Subslice(slashIndex + 1), out condition)) { Builder.LogWarning($"Failed to parse compound pattern 1 {pattern} from: {parameterText}"); return(false); } pattern = pattern.Subslice(0, slashIndex); } if (parameters.Length >= 2) { pattern2 = parameters[1]; slashIndex = pattern2.IndexOf('/'); if (slashIndex >= 0) { if (!TryParseFlag(pattern2.Subslice(slashIndex + 1), out condition2)) { Builder.LogWarning($"Failed to parse compound pattern 2 {pattern2} from: {parameterText}"); return(false); } pattern2 = pattern2.Subslice(0, slashIndex); } if (parameters.Length >= 3) { pattern3 = parameters[2]; Builder.EnableOptions(AffixConfigOptions.SimplifiedCompound); } } entries.Add(new PatternEntry( Builder.Dedup(pattern.ToString()), Builder.Dedup(pattern2.ToString()), Builder.Dedup(pattern3.ToString()), condition, condition2)); return(true); }
// re-use string keys using lru cache string StringFromCache(StringSlice slice) { int length = _stringCache.Length; int lowestCounter = int.MaxValue; int lowestCounterIndex = 0; for (int i = 0; i < length; ++i) { if (slice.Equals(_stringCache[i].key)) { _stringCache[i].counter = ++_stringCacheCounter; return(_stringCache[i].result); } var counter = _stringCache[i].counter; if (counter < lowestCounter) { lowestCounter = counter; lowestCounterIndex = i; } } string result = slice.ToString(); _stringCache[lowestCounterIndex].key = slice; _stringCache[lowestCounterIndex].result = result; _stringCache[lowestCounterIndex].counter = ++_stringCacheCounter; return(result); }
/// <summary> /// Parses the given string into a TagString. /// </summary> public void Parse(ref TagString outTarget, StringSlice inInput, object inContext = null) { if (outTarget == null) { outTarget = new TagString(); } else { outTarget.Clear(); } if (inInput.IsEmpty) { return; } m_RichBuilder.Length = 0; bool bModified; ProcessInput(inInput, outTarget, inContext, out bModified); if (bModified) { outTarget.RichText = m_RichBuilder.Flush(); outTarget.VisibleText = m_StrippedBuilder.Flush(); } else { string originalString = inInput.ToString(); outTarget.RichText = outTarget.VisibleText = originalString; m_RichBuilder.Length = 0; m_StrippedBuilder.Length = 0; } }
protected bool ParseCodeOptions( BlockProcessor state, ref StringSlice line, IFencedBlock fenced, char openingCharacter) { if (!(fenced is AnnotatedCodeBlock annotatedBlock)) { return(false); } var result = _codeFenceAnnotationsParser.TryParseCodeFenceOptions( line.ToString(), state.Context); switch (result) { case FailedCodeFenceOptionParseResult failed: foreach (var errorMessage in failed.ErrorMessages) { annotatedBlock.Diagnostics.Add(errorMessage); } return(true); case SuccessfulCodeFenceOptionParseResult codeResult: annotatedBlock.Annotations = codeResult.Annotations; return(true); } return(false); }
/// <summary> /// Returns the branch name for source control. /// </summary> static public string GetSourceControlBranchName() { try { if (Directory.Exists(".git")) { string headData = File.ReadAllText(".git/HEAD"); foreach (var line in StringSlice.EnumeratedSplit(headData, new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { TagData tag = TagData.Parse(line, TagStringParser.RichTextDelimiters); if (tag.Id == "ref") { StringSlice data = tag.Data; if (data.StartsWith("refs/heads/")) { data = data.Substring(11); } return(data.ToString()); } } } // TODO: More version control types? svn? return(null); } catch (Exception e) { Debug.LogException(e); return(null); } }
public void Create_CreateFlexiSectionHeadingBlock() { // Arrange const int dummyColumn = 12; const int dummyLineIndex = 5; var dummyLine = new StringSlice("dummyLine", 4, 8); BlockProcessor dummyBlockProcessor = MarkdigTypesFactory.CreateBlockProcessor(); dummyBlockProcessor.Line = dummyLine; dummyBlockProcessor.LineIndex = dummyLineIndex; dummyBlockProcessor.Column = dummyColumn; Mock <BlockParser> dummyBlockParser = _mockRepository.Create <BlockParser>(); Mock <IFlexiSectionBlockOptions> dummyFlexiSectionBlockOptions = _mockRepository.Create <IFlexiSectionBlockOptions>(); Mock <FlexiSectionHeadingBlockFactory> mockTestSubject = CreateMockFlexiSectionHeadingBlockFactory(); mockTestSubject.CallBase = true; mockTestSubject.Setup(t => t.SetupIDGenerationAndReferenceLinking(It.IsAny <FlexiSectionHeadingBlock>(), dummyFlexiSectionBlockOptions.Object, dummyBlockProcessor)); // Act FlexiSectionHeadingBlock result = mockTestSubject.Object.Create(dummyBlockProcessor, dummyFlexiSectionBlockOptions.Object, dummyBlockParser.Object); // Assert _mockRepository.VerifyAll(); Assert.Equal(dummyColumn, result.Column); Assert.Equal(dummyLine.Start, result.Span.Start); Assert.Equal(dummyLine.End, result.Span.End); Assert.Equal(dummyLineIndex, result.Line); Assert.Equal(dummyLine.ToString(), result.Lines.ToString()); }
protected bool ParseCodeOptions( BlockProcessor state, ref StringSlice line, IFencedBlock fenced) { if (!(fenced is AnnotatedCodeBlock codeLinkBlock)) { return(false); } var result = codeFenceAnnotationsParser.TryParseCodeFenceOptions(line.ToString(), state.Context); switch (result) { case NoCodeFenceOptions _: return(false); case FailedCodeFenceOptionParseResult failed: foreach (var errorMessage in failed.ErrorMessages) { codeLinkBlock.Diagnostics.Add(errorMessage); } break; case SuccessfulCodeFenceOptionParseResult successful: codeLinkBlock.Annotations = successful.Annotations; break; } return(true); }
private bool PlantUmlInfoParser(BlockProcessor state, ref StringSlice line, IFencedBlock fenced, char openingCharacter) { string infoString; string argString = null; var c = line.CurrentChar; // An info string cannot contain any backsticks int firstSpace = -1; for (int i = line.Start; i <= line.End; i++) { c = line.Text[i]; if (c == '`') { return(false); } if (firstSpace < 0 && c.IsSpaceOrTab()) { firstSpace = i; } } if (firstSpace > 0) { infoString = line.Text.Substring(line.Start, firstSpace - line.Start).Trim(); // Skip any spaces after info string firstSpace++; while (true) { c = line[firstSpace]; if (c.IsSpaceOrTab()) { firstSpace++; } else { break; } } argString = line.Text.Substring(firstSpace, line.End - firstSpace + 1).Trim(); } else { infoString = line.ToString().Trim(); } if (infoString != "plantuml") { return(false); } fenced.Info = HtmlHelper.Unescape(infoString); fenced.Arguments = HtmlHelper.Unescape(argString); return(true); }
public void ComponentParserReadUntil() { TestComponentParser parser = new TestComponentParser(); StringSlice slice = new StringSlice("[!clientId:NameOfComponent(- or |)] # comment", 2, 45); StringSlice clientId = parser.CallReadUntil(slice, ':'); Expect.AreEqual("clientId", clientId.ToString()); }
public static string NextPart(ref string text) { StringSlice ssText = StringSlice.Prepare(text); StringSlice ssResult = SliceNextPart(ref ssText); text = ssText.ToString(); return(ssResult.ToString()); }
public static StringSlice Concat(StringSlice ssA, StringSlice ssB) { if (object.ReferenceEquals(ssA.str, ssB.str)) { if (ssA.offset + ssA.length == ssB.offset) { return(StringSlice.Prepare(ssA.str, ssA.offset, ssA.length + ssB.length)); } } return(StringSlice.Prepare(ssA.ToString() + ssB.ToString())); }
static private void SetReflectedObject(UnityEngine.Object inRoot, string inPath, object inValue) { inPath = inPath.Replace("Array.data", ""); // locate the parent object StringSlice path = inPath; int lastDot = path.LastIndexOf('.'); if (lastDot < 0) { return; } StringSlice parentPath = path.Substring(0, lastDot); StringSlice fieldName = path.Substring(lastDot + 1); object parentObject = LocateReflectedObject(inRoot, parentPath.ToString()); if (parentObject == null) { return; } Type objType = parentObject.GetType(); int arrayIdx = -1; // capture array if (fieldName.EndsWith(']')) { int elementIndexStart = fieldName.IndexOf('['); int length = fieldName.Length - elementIndexStart - 1; StringSlice elementIndexSlice = fieldName.Substring(elementIndexStart + 1, length); arrayIdx = Convert.ToInt32(elementIndexSlice.ToString()); fieldName = fieldName.Substring(0, elementIndexStart); } FieldInfo field = objType.GetField(fieldName.ToString(), InstanceBindingFlags); if (field == null) { return; } if (arrayIdx >= 0) { IList list = field.GetValue(parentObject) as IList; if (list != null) { list[arrayIdx] = inValue; } return; } field.SetValue(parentObject, inValue); }
private static bool TryParseNumberFlag(StringSlice text, out FlagValue value) { if (!text.IsEmpty && IntEx.TryParseInvariant(text.ToString(), out int integerValue) && integerValue >= char.MinValue && integerValue <= char.MaxValue) { value = new FlagValue(unchecked ((char)integerValue)); return(true); } value = default(FlagValue); return(false); }
public void Collapse_CollapsesLeadingWhitespace(string dummyLine, float dummyCollapseLength, string expectedResult) { // Arrange var testSubject = new LeadingWhitespaceEditorService(); var dummyStringSlice = new StringSlice(dummyLine); // Act testSubject.Collapse(ref dummyStringSlice, dummyCollapseLength); // Assert Assert.Equal(expectedResult, dummyStringSlice.ToString()); }
public void Indent_IndentsStringSlice(string dummyLine, int dummyIndentLength, string expectedResult) { // Arrange var testSubject = new LeadingWhitespaceEditorService(); var dummyStringSlice = new StringSlice(dummyLine); // Act StringSlice result = testSubject.Indent(dummyStringSlice, dummyIndentLength); // Assert Assert.Equal(expectedResult, result.ToString()); }
public void Dedent_DedentsLeadingWhitespace(string dummyLine, int dummyDedentLength, string expectedResult) { // Arrange var testSubject = new LeadingWhitespaceEditorService(); var dummyStringSlice = new StringSlice(dummyLine); // Act testSubject.Dedent(ref dummyStringSlice, dummyDedentLength); // Assert Assert.Equal(expectedResult, dummyStringSlice.ToString()); }
public override bool Match(InlineProcessor processor, ref StringSlice slice) { var _isMatch = false; int _start, _end; var _url = ""; char _current; var _fullSlice = slice.ToString().ToLower().TrimStart(OpeningCharacters); if (!slice.PeekCharExtra(-1).IsWhiteSpaceOrZero()) { return(_isMatch); } if (_configuration.BaseUrls.Where(u => _fullSlice.StartsWith(u)).Count() == 0) { return(_isMatch); } _start = slice.Start; _end = _start; _current = slice.NextChar(); while (_current != ']') { _url += _current; _end = slice.Start; _current = slice.NextChar(); } if (_current == ']') { slice.NextChar(); var _inlineStart = processor.GetSourcePosition(slice.Start, out int _line, out int _column); processor.Inline = new EmbeddedGist { Span = { Start = _inlineStart, End = _inlineStart + (_end - _start) + 1 }, Line = _line, Column = _column, Url = _url }; _isMatch = true; } return(_isMatch); }
public override string ToString() { if (Id.IsEmpty) { return(Data.ToString()); } if (Data.IsEmpty) { return(Id.ToString()); } return(string.Format("{0}: {1}", Id, Data)); }
/// <summary> /// Returns the parent property. /// </summary> static public SerializedProperty FindPropertyParent(this SerializedProperty inProperty) { StringSlice path = inProperty.propertyPath.Replace("Array.data", ""); int lastDot = path.LastIndexOf('.'); if (lastDot < 0) { return(null); } StringSlice parentPath = path.Substring(0, lastDot); return(inProperty.serializedObject.FindProperty(parentPath.ToString())); }
/// <summary> /// Tries to open a section tag using the slice /// </summary> /// <param name="processor">The processor</param> /// <param name="slice">The slice</param> /// <returns>The result of the match</returns> public override ParserState TryOpenBlock(Processor processor, ref StringSlice slice) { var tagStart = slice.Start - processor.CurrentTags.StartTag.Length; var index = slice.Start; while (slice[index].IsWhitespace()) { index++; } var match = slice[index]; if (match == OpeningTagDelimiter) { slice.Start = index + 1; // Skip delimiter while (slice.CurrentChar.IsWhitespace()) { slice.NextChar(); } var startIndex = slice.Start; // Take characters until closing tag while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag)) { slice.NextChar(); } var sectionName = slice.ToString(startIndex, slice.Start).TrimEnd(); var contentStartPosition = slice.Start + processor.CurrentTags.EndTag.Length; var sectionTag = new SectionToken { SectionName = sectionName, StartPosition = tagStart, ContentStartPosition = contentStartPosition, Parser = this, IsClosed = false }; processor.CurrentToken = sectionTag; slice.Start = contentStartPosition; return(ParserState.Break); } return(ParserState.Continue); }
/// <inheritdoc /> public virtual StringSlice Indent(StringSlice line, int indentLength) { if (indentLength < 0) { throw new ArgumentOutOfRangeException(nameof(indentLength), string.Format(Strings.ArgumentOutOfRangeException_Shared_ValueCannotBeNegative, indentLength)); } if (indentLength == 0) { return(line); } // TODO difficult to avoid these allocations without changes to Markdig. While this implementation isn't efficient, it is very useful. return(new StringSlice(new string(' ', indentLength) + line.ToString())); }
/// <summary> /// Try to create a block close tag /// </summary> /// <param name="processor">The processor</param> /// <param name="slice">the slice</param> /// <param name="token">the current block tag</param> /// <returns>If the close was successful</returns> public override bool TryClose(Processor processor, ref StringSlice slice, BlockToken token) { var sectionTag = (SectionToken)token; while (slice.CurrentChar.IsWhitespace()) { slice.NextChar(); } var blockStart = slice.Start - processor.CurrentTags.StartTag.Length; slice.Start = slice.Start + 1; // Skip the slash while (slice.CurrentChar.IsWhitespace()) { slice.NextChar(); } var startIndex = slice.Start; // Take characters until closing tag while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag)) { slice.NextChar(); } var sectionName = slice.ToString(startIndex, slice.Start).TrimEnd(); if (sectionTag.SectionName == sectionName) { var tagEnd = slice.Start + processor.CurrentTags.EndTag.Length; var endTag = new SectionEndToken { SectionName = sectionName, EndPosition = tagEnd, ContentEndPosition = blockStart, IsClosed = true }; processor.CurrentToken = endTag; slice.Start += processor.CurrentTags.EndTag.Length; return(true); } throw new StubbleException($"Cannot close Block '{sectionName}' at {blockStart}. There is already an unclosed Block '{sectionTag.SectionName}'"); }
internal CodeBlockInfo(FencedCodeBlock codeBlock, StringSlice slice) { Info = codeBlock.Info ?? string.Empty; Arguments = codeBlock.Arguments ?? string.Empty; Lines = codeBlock.Lines; CodeBlockSlice = slice; Source = CodeBlockSlice.Text; int contentStart = Lines.Lines[0].Position; var lastLine = Lines.Last(); int contentEnd = lastLine.Position + lastLine.Slice.Length - 1; ContentSpan = new SourceSpan(contentStart, contentEnd); ContentSlice = CodeBlockSlice.Reposition(ContentSpan); Content = ContentSlice.ToString(); }
public override bool Match(InlineProcessor processor, ref StringSlice slice) { // [!clientId:NameOfComponent(- or |)] # comment // ``` // init: function(component) {} // click: function(component) {} // mouseover: function(component){} // ... other event handlers etc ... // ``` bool match = false; int start = slice.Start; int end = slice.Start; char openSquareBracket = slice.PeekCharExtra(-1); char shouldBeWhitespace = slice.PeekCharExtra(-2); if (shouldBeWhitespace.IsWhiteSpaceOrZero() && openSquareBracket == '[') { slice.NextChar(); StringSlice clientId = ReadUntil(slice, ':', out end); StringSlice nameOfComponent = ReadUntil(slice, ']', out end); string nameOfComponentString = nameOfComponent.ToString(); //bool block = true; //if (nameOfComponentString.EndsWith("|")) //{ // nameOfComponentString = nameOfComponentString.Truncate(1); // block = false; //} if (ComponentResolver.IsValidComponentName(nameOfComponentString, out LeafInline component)) { int inlineStart = processor.GetSourcePosition(slice.Start, out int line, out int column); component.Span.Start = inlineStart; component.Span.End = inlineStart + (end - start) + 1; processor.Inline = component; match = true; } } return(match); }
static void AddTicketLink(InlineProcessor processor, StringSlice slice, int charactersConsumedInReference, Uri uri) { int line, column; var startPosition = slice.Start; var endPosition = startPosition + charactersConsumedInReference - 1; var linkText = new StringSlice(slice.Text, startPosition, endPosition); var link = new TicketLinkInline { Span = { Start = processor.GetSourcePosition(startPosition, out line, out column), }, Line = line, Column = column, Url = uri.ToString(), IsClosed = true, IsAutoLink = true, Title = $"Navigate to {linkText.ToString()}", }; link.Span.End = endPosition; link.UrlSpan = link.Span; link.GetAttributes().AddClass(TicketLinkClass); var linkContent = new LiteralInline { Span = link.Span, Line = line, Column = column, Content = linkText, IsClosed = true, }; link.AppendChild(linkContent); processor.Inline = link; }
public static StringSlice Concat(StringSlice ssA, string sB) { return StringSlice.Prepare(ssA.ToString() + sB); }
public static StringSlice Concat(StringSlice ssA, StringSlice ssB) { if (object.ReferenceEquals(ssA.str, ssB.str)) { if (ssA.offset + ssA.length == ssB.offset) { return StringSlice.Prepare(ssA.str, ssA.offset, ssA.length + ssB.length); } } return StringSlice.Prepare(ssA.ToString() + ssB.ToString()); }
public readonly override string ToString() { return(Slice.ToString()); }
public override bool Match(Processor processor, ref StringSlice slice) { if (processor is null) { throw new System.ArgumentNullException(nameof(processor)); } var tagStart = slice.Start - processor.CurrentTags.StartTag.Length; var index = slice.Start; while (slice[index].IsWhitespace()) { index++; } var nameStart = index; // Skip whitespace or until end tag while (!slice[index].IsWhitespace() && !slice.Match(processor.CurrentTags.EndTag, index - slice.Start)) { index++; } var name = slice.ToString(nameStart, index); // Skip whitespace or until end tag while (slice[index].IsWhitespace() && !slice.Match(processor.CurrentTags.EndTag, index - slice.Start)) { index++; } if (!_helperMap.TryGetValue(name, out var helperRef)) { return(false); } int contentEnd; var argsList = ImmutableArray <HelperArgument> .Empty; if (helperRef.ArgumentTypes.Length > 1) { var argsStart = index; slice.Start = index; while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag)) { slice.NextChar(); } var args = new StringSlice(slice.Text, argsStart, slice.Start - 1); args.TrimEnd(); contentEnd = args.End + 1; argsList = ParseArguments(new StringSlice(args.Text, args.Start, args.End)); } else { while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag)) { slice.NextChar(); } contentEnd = slice.Start; } if (!slice.Match(processor.CurrentTags.EndTag)) { throw new StubbleException($"Unclosed Tag at {slice.Start.ToString(CultureInfo.InvariantCulture)}"); } var tag = new HelperToken { TagStartPosition = tagStart, ContentStartPosition = nameStart, Name = name, Args = argsList, ContentEndPosition = contentEnd, TagEndPosition = slice.Start + processor.CurrentTags.EndTag.Length, IsClosed = true }; slice.Start += processor.CurrentTags.EndTag.Length; processor.CurrentToken = tag; processor.HasSeenNonSpaceOnLine = true; return(true); }