public List <TocEntry> ExtractTocEntries(string markdown) { var pipeline = DocgenDefaults.GetDefaultPipeline(); var document = Markdig.Markdown.Parse(markdown, pipeline); var result = new List <TocEntry>(); void WalkBlock(Block block) { if (block is HeadingBlock headingBlock) { result.Add(new TocEntry { Level = headingBlock.Level, Id = headingBlock.TryGetAttributes().Id, Title = MarkdownHelpers.RenderLeafInlineRaw(headingBlock) }); } if (block is CustomContainer customContainer) { foreach (var child in customContainer) { WalkBlock(child); } } } foreach (var item in document) { WalkBlock(item); } return(result); }
public MarkdownRenderResult RenderMarkdown(string markdown) { var yaml = _yamlParser.ParseYaml(markdown); var html = Markdig.Markdown.ToHtml(yaml.Markdown, DocgenDefaults.GetDefaultPipeline()); if (!string.IsNullOrEmpty(html)) { html = html.TrimEnd(Environment.NewLine.ToCharArray()); } return(new MarkdownRenderResult(yaml.Yaml, html)); }
public string TransformLinks(string markdown, Func <string, string> func) { using (var stringWriter = new StringWriter()) { var transformRenderer = new MarkdownTransformRenderer(stringWriter, markdown); transformRenderer.ObjectRenderers.Add(new LinkTransformRenderer(func)); var document = Markdig.Markdown.Parse(markdown, DocgenDefaults.GetDefaultPipeline()); transformRenderer.Render(document); // Flush any remaining markdown content. transformRenderer.Writer.Write(transformRenderer.TakeNext(transformRenderer.OriginalMarkdown.Length - transformRenderer.LastWrittenIndex)); stringWriter.Flush(); return(stringWriter.ToString()); } }
public async Task <IManualWeb> BuildManual() { var webBuilder = _serviceProvider.GetRequiredService <IWebBuilder>(); var resourcesDirectory = Path.Combine(_options.ContentDirectory, "resources"); if (await Task.Run(() => Directory.Exists(resourcesDirectory))) { webBuilder.RegisterDirectory("/resources", resourcesDirectory); } webBuilder.RegisterMvc("/", new { controller = "Home", action = "Index" }); var languages = await _manualTranslations.GetLanguages(); foreach (var language in languages) { webBuilder.RegisterMvc($"/prince/{language}/template", new { controller = "Prince", action = "Template", language }); webBuilder.RegisterMvc($"/prince/{language}/output.pdf", new { controller = "Prince", action = "Pdf", language }); } // Register our static files. webBuilder.RegisterDirectory("/Users/pknopf/git/docgen/src/DocGen.Web.Manual/Internal/Resources/wwwroot"); CoversheetConfig coversheet = null; var sections = new ManualSectionStore(); foreach (var markdownFile in await Task.Run(() => Directory.GetFiles(_options.ContentDirectory, "*.md"))) { var content = await Task.Run(() => File.ReadAllText(markdownFile)); var yaml = _yamlParser.ParseYaml(content); if (yaml.Yaml == null) { yaml = new YamlParseResult(JsonConvert.DeserializeObject("{}"), yaml.Markdown); } var type = "Content"; if (!string.IsNullOrEmpty((string)yaml.Yaml.Type)) { type = yaml.Yaml.Type; } switch (type) { case "Coversheet": if (coversheet != null) { throw new DocGenException("Multiple coversheets detected"); } coversheet = new CoversheetConfig(); coversheet.ProductImage = yaml.Yaml.ProductImage; coversheet.ProductLogo = yaml.Yaml.ProductLogo; coversheet.Model = yaml.Yaml.Model; coversheet.Text = yaml.Yaml.Text; break; case "Content": var order = (int?)yaml.Yaml.Order; var title = (string)yaml.Yaml.Title; if (string.IsNullOrEmpty(title)) { throw new DocGenException($"The file {markdownFile} needs a title."); } foreach (var language in languages) { sections.AddMarkdown(language, _translator.Translate(language, title) , order ?? 0, _markdownTransformer.TransformMarkdown( yaml.Markdown, DocgenDefaults.GetDefaultPipeline(), x => _translator.Translate(language, x)), markdownFile); } break; default: throw new DocGenException("Unknown contente type"); } } if (coversheet == null) { throw new DocGenException("You must provide a coversheet"); } webBuilder.RegisterServices(services => { services.AddMvc(); services.Configure <RazorViewEngineOptions>(options => { options.FileProviders.Add(new PhysicalFileProvider("/Users/pknopf/git/docgen/src/DocGen.Web.Manual/Internal/Resources")); var templateDirectory = Path.Combine(_options.ContentDirectory, "templates"); if (Directory.Exists(templateDirectory)) { options.FileProviders.Add(new PhysicalFileProvider(templateDirectory)); } }); services.AddSingleton(_translator); services.AddSingleton(_manualTranslations); services.AddSingleton(sections); services.AddSingleton(coversheet); services.AddSingleton(_symbolGlossaryStore); // These regitrations are so that our controllers can inject core DocGen services. DocGen.Core.Services.Register(services); }); return(new ManualWeb(webBuilder)); }
public async Task RegenerateTemplate() { var translations = new List <string>(); foreach (var markdownFile in await Task.Run(() => Directory.GetFiles(_options.ContentDirectory, "*.md"))) { var content = await Task.Run(() => File.ReadAllText(markdownFile)); var yaml = _yamlParser.ParseYaml(content); if (yaml.Yaml == null) { yaml = new YamlParseResult(JsonConvert.DeserializeObject("{}"), yaml.Markdown); } var type = "Content"; if (!string.IsNullOrEmpty((string)yaml.Yaml.Type)) { type = yaml.Yaml.Type; } switch (type) { case "Content": var order = (int?)yaml.Yaml.Order; _markdownTransformer.TransformMarkdown(yaml.Markdown, DocgenDefaults.GetDefaultPipeline(), value => { if (!translations.Contains(value)) { translations.Add(value); } return(value); }); break; } } // Add some translations that we have hardcoded in our templates. if (!translations.Contains("Table of contents")) { translations.Add("Table of contents"); } // Now that we have the translations of all of our documents, let's generate the POT file. var destination = Path.Combine(_options.ContentDirectory, "translations", "template.pot"); await Task.Run(() => { var parentDirectory = Path.GetDirectoryName(destination) ?? ""; if (!Directory.Exists(parentDirectory)) { Directory.CreateDirectory(parentDirectory); } if (File.Exists(destination)) { File.Delete(destination); } using (var file = File.OpenWrite(destination)) using (var writer = new StreamWriter(file)) SharpGettext.SharpGettext.GeneratePOT( new POTemplateHeader { Language = "en-US" }, translations.Select(x => new POTranslation { Text = x }).ToList(), writer); }); // Now that we have our POT files, let's update all of our translations. await Task.Run(async() => { foreach (var file in Directory.GetFiles(Path.Combine(_options.ContentDirectory, "translations"), "*.po")) { await RunAsync("msgmerge", $"-U \"{file}\" \"{destination}\""); } }); }