/// <summary> /// Identifies the <see cref="WikiLink"/>s in the given <paramref name="markdown"/>. /// </summary> /// <param name="options">An <see cref="WikiOptions"/> instance.</param> /// <param name="dataStore">An <see cref="IDataStore"/> instance.</param> /// <param name="markdown">The markdown.</param> /// <param name="title">The title of the item.</param> /// <param name="wikiNamespace">The namespace of the item.</param> /// <returns> /// A <see cref="List{T}"/> of <see cref="WikiLink"/>s. /// </returns> protected static List <WikiLink> GetWikiLinks( IWikiOptions options, IDataStore dataStore, string?markdown, string?title = null, string?wikiNamespace = null) => string.IsNullOrEmpty(markdown) ? new List <WikiLink>() : Markdown.Parse(markdown, WikiConfig.GetMarkdownPipeline(options, dataStore)) .Descendants <WikiLinkInline>() .Where(x => !x.IsWikipedia &&
public WikiSite(WikiConfig config, MasterRepository masterRepository, ISourceWatcher sourceWatcher, IPageCache pageCache) { wikiConfig = config; repository = masterRepository; watcher = sourceWatcher; generator = new WikiGenerator(wikiConfig.Convertor, wikiConfig.RootWikiPath, pageCache); siteGeneratorScheduler = new EventLoopScheduler(threadStart => new Thread(threadStart) { Name = "SiteGenerator" }); }
public TestWikiSite() { // setup initial site structure Directory.CreateDirectory(Path.Combine(".", "subdir1")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2", "subdir3")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2", "subdir3", "subdir4")); System.IO.File.AppendAllText(Path.Combine(".", "index.md"), "Hello World"); System.IO.File.AppendAllText(Path.Combine(".", "subdir1", "index.md"), "Hello World Sub Directory"); System.IO.File.AppendAllText(Path.Combine(".", "subdir1", "subdir2", "index.md"), "Hello World Sub Sub Directory"); createdDirectories = new List <string>(); updatedDirectories = new List <string>(); deletedDirectories = new List <string>(); movedDirectories = new List <string>(); createdPages = new List <string>(); updatedPages = new List <string>(); deletedPages = new List <string>(); movedPages = new List <string>(); Convertor convertor = new Convertor(new MarkdownSharpDialogue()); WikiConfig wikiConfig = new WikiConfig() { SiteName = "Tester", RootSourcePath = PathHelper.GetFullPath("."), RootWikiPath = PathHelper.GetFullPath(".", "wiki"), Convertor = new Convertor(new MarkdownSharpDialogue()) }; site = new WikiSite(wikiConfig, new MasterRepository(convertor.FileExtension), new SourceWatcher(wikiConfig.RootSourcePath, wikiConfig.Convertor.FileSearchString), new PageCache() ); // setup event handlers site.DirectoryAdded += (source, args) => createdDirectories.Add(args.WikiUrl); site.DirectoryUpdated += (source, args) => updatedDirectories.Add(args.WikiUrl); site.DirectoryDeleted += (source, args) => deletedDirectories.Add(args.WikiUrl); site.DirectoryMoved += (source, args) => movedDirectories.Add(args.WikiUrl); site.PageAdded += (source, args) => createdPages.Add(args.WikiUrl); site.PageUpdated += (source, args) => updatedPages.Add(args.WikiUrl); site.PageDeleted += (source, args) => deletedPages.Add(args.WikiUrl); site.PageMoved += (source, args) => movedPages.Add(args.WikiUrl); site.Start(); Thread.Sleep(1000); }
public TestWikiSite() { // setup initial site structure Directory.CreateDirectory(Path.Combine(".", "subdir1")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2", "subdir3")); Directory.CreateDirectory(Path.Combine(".", "subdir1", "subdir2", "subdir3", "subdir4")); System.IO.File.AppendAllText(Path.Combine(".", "index.md"), "Hello World"); System.IO.File.AppendAllText(Path.Combine(".", "subdir1", "index.md"), "Hello World Sub Directory"); System.IO.File.AppendAllText(Path.Combine(".", "subdir1", "subdir2", "index.md"), "Hello World Sub Sub Directory"); createdDirectories = new List<string>(); updatedDirectories = new List<string>(); deletedDirectories = new List<string>(); movedDirectories = new List<string>(); createdPages = new List<string>(); updatedPages = new List<string>(); deletedPages = new List<string>(); movedPages = new List<string>(); Convertor convertor = new Convertor(new MarkdownSharpDialogue()); WikiConfig wikiConfig = new WikiConfig() { SiteName = "Tester", RootSourcePath = PathHelper.GetFullPath("."), RootWikiPath = PathHelper.GetFullPath(".", "wiki"), Convertor = new Convertor(new MarkdownSharpDialogue()) }; site = new WikiSite(wikiConfig, new MasterRepository(convertor.FileExtension), new SourceWatcher(wikiConfig.RootSourcePath, wikiConfig.Convertor.FileSearchString), new PageCache() ); // setup event handlers site.DirectoryAdded += (source, args) => createdDirectories.Add(args.WikiUrl); site.DirectoryUpdated += (source, args) => updatedDirectories.Add(args.WikiUrl); site.DirectoryDeleted += (source, args) => deletedDirectories.Add(args.WikiUrl); site.DirectoryMoved += (source, args) => movedDirectories.Add(args.WikiUrl); site.PageAdded += (source, args) => createdPages.Add(args.WikiUrl); site.PageUpdated += (source, args) => updatedPages.Add(args.WikiUrl); site.PageDeleted += (source, args) => deletedPages.Add(args.WikiUrl); site.PageMoved += (source, args) => movedPages.Add(args.WikiUrl); site.Start(); Thread.Sleep(1000); }
public bool TryGetConfig(string siteName, out WikiConfig value) { string safeName = CreateSafeName(siteName); Tuple <WikiConfig, MasterRepository, IPageCache> tuple; if (configMap.TryGetValue(siteName, out tuple)) { value = tuple.Item1; return(true); } else { value = null; return(false); } }
public static async Task SetupClient(TestContext context) { generalConfig = GeneralConfig.Instance.Value; var conf = new BacklogJpConfigure(generalConfig.SpaceKey); conf.ApiKey = generalConfig.ApiKey; client = new BacklogClientFactory(conf).NewClient(); var users = await client.GetUsersAsync(); projectKey = generalConfig.ProjectKey; var project = await client.GetProjectAsync(projectKey); projectId = project.Id; wikiConfig = WikiConfig.Instance.Value; ownUser = await client.GetMyselfAsync(); }
/// <summary> /// Gets a preview of the given markdown's rendered HTML. /// </summary> /// <param name="options">An <see cref="IWikiOptions"/> instance.</param> /// <param name="dataStore">An <see cref="IDataStore"/> instance.</param> /// <param name="markdown">The markdown content.</param> /// <returns>A preview of the rendered HTML.</returns> public static string RenderPreview(IWikiOptions options, IDataStore dataStore, string?markdown) { if (string.IsNullOrWhiteSpace(markdown)) { return(string.Empty); } var document = Markdown.Parse(markdown, WikiConfig.GetMarkdownPipeline(options, dataStore)); if (AnyPreviews(document)) { TrimNonPreview(document); } else { var minCharactersAvailable = PreviewCharacterMin; var maxCharactersAvailable = PreviewCharacterMax; Trim(document, ref minCharactersAvailable, ref maxCharactersAvailable); } string html; using (var writer = new StringWriter()) { var renderer = new HtmlRenderer(writer); WikiConfig.GetMarkdownPipeline(options, dataStore).Setup(renderer); renderer.Render(document); html = writer.ToString(); } if (!string.IsNullOrWhiteSpace(html) && options.Postprocessors is not null) { foreach (var preprocessor in options.Postprocessors) { html = preprocessor.Process.Invoke(html); } } return(WikiConfig.GetHtmlSanitizer(options).Sanitize(html) ?? string.Empty); }
/// <summary> /// Renders the given <paramref name="markdown"/> as HTML. /// </summary> /// <param name="options">An <see cref="IWikiOptions"/> instance.</param> /// <param name="dataStore">An <see cref="IDataStore"/> instance.</param> /// <param name="markdown">The markdown content.</param> /// <returns>The rendered HTML.</returns> public static string RenderHtml(IWikiOptions options, IDataStore dataStore, string?markdown) { if (string.IsNullOrWhiteSpace(markdown)) { return(string.Empty); } var html = Markdown.ToHtml(markdown, WikiConfig.GetMarkdownPipeline(options, dataStore)); if (string.IsNullOrWhiteSpace(html)) { return(string.Empty); } if (options.Postprocessors is not null) { foreach (var preprocessor in options.Postprocessors) { html = preprocessor.Process.Invoke(html); } } return(WikiConfig.GetHtmlSanitizer(options).Sanitize(html)); }
/// <summary> /// Gets the given markdown content as plain text (i.e. strips all formatting). /// </summary> /// <param name="options">An <see cref="IWikiOptions"/> instance.</param> /// <param name="dataStore">An <see cref="IDataStore"/> instance.</param> /// <param name="markdown">The markdown content.</param> /// <param name="characterLimit">The maximum number of characters to return.</param> /// <param name="singleParagraph"> /// If true, stops after the first paragraph break, even still under the allowed character limit. /// </param> /// <returns>The plain text.</returns> public static string FormatPlainText( IWikiOptions options, IDataStore dataStore, string?markdown, int?characterLimit = 200, bool singleParagraph = true) { if (string.IsNullOrEmpty(markdown)) { return(string.Empty); } if (singleParagraph && markdown.Length > 1) { var paraIndex = markdown.IndexOf(Environment.NewLine + Environment.NewLine, 1); if (paraIndex > 0) { markdown = markdown.Substring(0, paraIndex); } } if (characterLimit.HasValue && markdown.Length > characterLimit.Value * 5) { markdown = markdown.Substring(0, characterLimit.Value * 5); } var html = Markdown.ToHtml(markdown, WikiConfig.GetMarkdownPipelinePlainText(options, dataStore)); if (string.IsNullOrWhiteSpace(html)) { return(string.Empty); } if (options.Postprocessors is not null) { foreach (var preprocessor in options.Postprocessors) { html = preprocessor.Process.Invoke(html); } } var sanitized = WikiConfig.HtmlSanitizerFull.Sanitize(html); if (characterLimit.HasValue && sanitized.Length > characterLimit) { var substring = sanitized.Substring(0, characterLimit.Value); var i = substring.Length - 1; var whitespace = false; for (; i > 0; i--) { if (substring[i].IsWhiteSpaceOrZero()) { whitespace = true; } else if (whitespace) { break; } } sanitized = whitespace ? substring.Substring(0, i + 1) : substring; } return(sanitized); }
public WikiModule(ServerConfig serverConfig) : base("/wiki") { config = serverConfig; fileReader = new FileReader(FileReaderPolicy.LimitedBlock, 500); // add top level "site" route Get["/{site}"] = parameters => { WikiConfig wikiConfig = null; MasterRepository masterRepository = null; if (config.TryGetConfig(parameters["site"], out wikiConfig) && config.TryGetMasterRepository(parameters["site"], out masterRepository)) { // TODO: Async-ify this var pageResults = masterRepository.GetAvailableAssets().Result; SiteModel model = new SiteModel() { IsPartialView = Request.Query.isPartial, WikiUrl = "/", SiteMap = pageResults }; Context.ViewBag.SiteName = wikiConfig.SiteName; return(View["Site.cshtml", model]); } else { return(HttpStatusCode.NotFound); } }; // add "directory" route, subpath should not contain a "." or a "/" Get[@"/{site}/(?<directory>[^\.]*)"] = parameters => { WikiConfig wikiConfig; if (config.TryGetConfig(parameters["site"], out wikiConfig) && Directory.Exists(Path.Combine(wikiConfig.RootWikiPath, parameters["directory"]))) { DirectoryModel model = new DirectoryModel() { IsPartialView = Request.Query.isPartial, WikiUrl = parameters["directory"], }; Context.ViewBag.SiteName = wikiConfig.SiteName; return(View["Directory.cshtml", model]); } else { return(HttpStatusCode.NotFound); } }; // add "page" route, subpath should always have a file extension (and therefore at least one ".") Get[@"/{site}/(?<page>.*\..*)"] = parameters => { WikiConfig wikiConfig = null; MasterRepository masterRepository = null; if (config.TryGetConfig(parameters["site"], out wikiConfig) && config.TryGetMasterRepository(parameters["site"], out masterRepository)) { // Async-ify var results = masterRepository.GetPageByWikiUrl(parameters["page"]).Result; if (results.Item1) { var results2 = TryGetPageContents(parameters["site"], results.Item2); if (results2.Item1) { PageModel model = new PageModel() { IsPartialView = Request.Query.isPartial, WikiUrl = parameters["page"], Contents = results2.Item2 }; Context.ViewBag.SiteName = wikiConfig.SiteName; return(View["Page.cshtml", model]); } else { // TODO: If the file doesn't exist we could potentially remove it from the cache return(HttpStatusCode.NotFound); } } else { // TODO: If the file doesn't exist we could potentially remove it from the cache return(HttpStatusCode.NotFound); } } else { return(HttpStatusCode.NotFound); } }; }