public void ExtractSnippet() { // Declare content const string content = @"Some Content Here"; // Mock file system IFileSystem fileSystem = new MockFileSystem(new Dictionary<string, MockFileData> { { "Content.txt", new MockFileData(content) } }); // Run the extraction DefaultSnippetExtractor extractor = new DefaultSnippetExtractor(); FileInfoBase fileInfoBase = fileSystem.FileInfo.FromFileName("Content.txt"); Extension.Model.PlainTextSnippet snippet = extractor.Extract(fileInfoBase, null) as Extension.Model.PlainTextSnippet; // Load the expected file content MemoryStream memoryStream = new MemoryStream(); using (var fileReader = new StreamReader(fileInfoBase.OpenRead())) using (var fileWriter = new StreamWriter(memoryStream)) { fileWriter.Write(fileReader.ReadToEnd()); } // Assert Assert.AreEqual(content, snippet.Text); }
/// <summary> /// Handles the snippet extension: /// @snippet language [filename] pattern /// /// where 'language' can be: cs, xml or txt. If something else, txt is used /// '[filename]' is evaluated relatively to the document location of the current document. /// 'pattern' is the pattern passed to the extractor, which is determined based on the language. This is Projbook code. /// /// The read snippet is wrapped in a fenced code block with language as language marker, except for txt, which will get 'nohighlight'. /// This fenced code block is then parsed again and that result is returned as b's data. /// </summary> /// <param name="b">The block to handle.</param> /// <returns></returns> private bool HandleSnippetExtension(Block b) { // skip @snippet if(!SkipString("@snippet")) { return false; } if(!SkipLinespace()) { return false; } // language var language = string.Empty; if(!SkipIdentifier(ref language)) { return false; } if(!SkipLinespace()) { return false; } // [filename] if(!this.SkipChar('[')) { return false; } // mark start of filename string this.Mark(); if(!this.Find(']')) { return false; } string filename = this.Extract(); if(string.IsNullOrWhiteSpace(filename)) { return false; } if(!SkipChar(']')) { return false; } if(!SkipLinespace()) { return false; } // pattern var patternStart = this.Position; SkipToEol(); var pattern = this.Input.Substring(patternStart, this.Position - patternStart); SkipToNextLine(); language = language.ToLowerInvariant(); ISnippetExtractor extractor = null; switch(language) { case "cs": extractor = new CSharpSnippetExtractor(); break; case "xml": extractor = new XmlSnippetExtractor(); break; default: // text language = "nohighlight"; extractor = new DefaultSnippetExtractor(); break; } // extract the snippet, then build the fenced block to return. var fullFilename = Path.Combine(Path.GetDirectoryName(m_markdown.SourceDocumentFilename) ?? string.Empty, filename); var snippetText = extractor.Extract(fullFilename, pattern) ?? string.Empty; b.BlockType = BlockType.codeblock; b.Data = language; var child = CreateBlock(); child.BlockType = BlockType.indent; child.Buf = snippetText; child.ContentStart = 0; child.ContentEnd = snippetText.Length; b.Children = new List<Block>() { child}; return true; }