Skip to content

Commit

Permalink
add inline shortcut for Markdig
Browse files Browse the repository at this point in the history
  • Loading branch information
dilyanrusev committed Sep 14, 2020
1 parent 529d58a commit 872197c
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ src/docfx.website.themes/default/fonts/
# deploy #
###############
tools/Deployment/.vscode/
tools/Deployment/out/
tools/Deployment/out/
/package_version_temp.txt
3 changes: 2 additions & 1 deletion src/Microsoft.DocAsCode.Dfm/DfmEngineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ public DfmEngineBuilder(Options options, string baseDir, string templateDir, IRe
{
throw new ArgumentException("MarkdownLinkInlineRule should exist!");
}

inlineRules.Insert(index + 1, new DfmXrefShortcutInlineRule());
inlineRules.Insert(index + 1, new DfmEmailInlineRule());
inlineRules.Insert(index + 1, new DfmFencesInlineRule());
inlineRules.Insert(index + 1, new DfmIncludeInlineShortcutRule());

// xref link inline rule must be before MarkdownLinkInlineRule
inlineRules.Insert(index, new DfmIncludeInlineRule());
inlineRules.Insert(index, new DfmIncludeInlineShortcutRule());

Replace<MarkdownTextInlineRule, DfmTextInlineRule>(inlineRules);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.DocAsCode.Dfm
public class DfmIncludeInlineShortcutRule : IMarkdownRule
{
public virtual string Name => "DfmIncludeInlineShortcut";
private static readonly Regex _inlineIncludeRegex = new Regex(@"@@(?<identifier>\w+)", RegexOptions.Compiled | RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10));
internal static readonly Regex _inlineIncludeRegex = new Regex(@"@@(?<identifier>\w+)", RegexOptions.Compiled | RegexOptions.IgnoreCase, TimeSpan.FromSeconds(10));
public virtual Regex Include => _inlineIncludeRegex;

public IMarkdownToken TryMatch(IMarkdownParser parser, IMarkdownParsingContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public void Setup(MarkdownPipelineBuilder pipeline)
{
pipeline.BlockParsers.AddIfNotAlready<InclusionBlockParser>();
pipeline.InlineParsers.InsertBefore<LinkInlineParser>(new InclusionInlineParser());

var inlineShortcut = new InclusionInlineShortcutParser();
pipeline.InlineParsers.InsertBefore<XrefInlineShortParser>(inlineShortcut);
pipeline.InlineParsers.AddIfNotAlready(inlineShortcut);
}

public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
Expand All @@ -38,6 +42,13 @@ public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
htmlRenderer.ObjectRenderers.Insert(0, new HtmlInclusionInlineRenderer(_context, inlinePipeline));
}

if (!htmlRenderer.ObjectRenderers.Contains<HtmlInclusionInlineShortcutRenderer>())
{
var inlinePipeline = LazyInitializer.EnsureInitialized(ref _inlinePipeline, () => CreateInlineOnlyPipeline(pipeline));

htmlRenderer.ObjectRenderers.Insert(0, new HtmlInclusionInlineShortcutRenderer(_context, inlinePipeline));
}

if (!htmlRenderer.ObjectRenderers.Contains<HtmlInclusionBlockRenderer>())
{
htmlRenderer.ObjectRenderers.Insert(0, new HtmlInclusionBlockRenderer(_context, pipeline));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.MarkdigEngine.Extensions
{
using Markdig;
using Markdig.Renderers;
using Markdig.Renderers.Html;
using System.Linq;

public class HtmlInclusionInlineShortcutRenderer : HtmlObjectRenderer<InclusionInlineShortcut>
{
private readonly MarkdownContext _context;
private readonly MarkdownPipeline _inlinePipeline;

public HtmlInclusionInlineShortcutRenderer(MarkdownContext context, MarkdownPipeline inlinePipeline)
{
_context = context;
_inlinePipeline = inlinePipeline;
}

protected override void Write(HtmlRenderer renderer, InclusionInlineShortcut inclusion)
{
var (content, includeFilePath) = _context.ReadFile(inclusion.IncludedFilePath, inclusion);

if (content == null)
{
_context.LogWarning("include-not-found", $"Cannot resolve '{inclusion.IncludedFilePath}' relative to '{InclusionContext.File}'.", inclusion);
renderer.Write(inclusion.GetRawToken());
return;
}

if (InclusionContext.IsCircularReference(includeFilePath, out var dependencyChain))
{
_context.LogWarning("circular-reference", $"Build has identified file(s) referencing each other: {string.Join(" --> ", dependencyChain.Select(file => $"'{file}'"))} --> '{includeFilePath}'", inclusion);
renderer.Write(inclusion.GetRawToken());
return;
}

using (InclusionContext.PushInclusion(includeFilePath))
{
renderer.Write(Markdown.ToHtml(content, _inlinePipeline));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.MarkdigEngine.Extensions
{
using Markdig.Syntax.Inlines;

public class InclusionInlineShortcut : ContainerInline
{
public string RawFilename { get; set; }

public string IncludedFilePath { get; set; }

public object ResolvedFilePath { get; set; }

public string GetRawToken() => $"@@{RawFilename}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DocAsCode.MarkdigEngine.Extensions
{
using Markdig.Helpers;
using Markdig.Parsers;
using Markdig.Syntax;

public class InclusionInlineShortcutParser : InlineParser
{
private const string StartString = "@@";

public InclusionInlineShortcutParser()
{
OpeningCharacters = new[] { '@' };
}

public override bool Match(InlineProcessor processor, ref StringSlice slice)
{
var startPosition = processor.GetSourcePosition(slice.Start, out var line, out var column);

if (!ExtensionsHelper.MatchStart(ref slice, StartString, false))
{
return false;
}

var str = StringBuilderCache.Local();

str.Append(slice.CurrentChar);

var c = slice.NextChar();
while (c.IsAlphaNumeric())
{
str.Append(c);
c = slice.NextChar();
}

if (str.Length == 0)
{
return false;
}

string symbol = str.ToString();
if (string.IsNullOrWhiteSpace(symbol))
{
return false;
}

processor.Inline = new InclusionInlineShortcut
{
RawFilename = symbol,
IncludedFilePath = $"~/includes/{symbol}.md",
Line = line,
Column = column,
Span = new SourceSpan(startPosition, processor.GetSourcePosition(slice.Start - 1)),
IsClosed = true,
};

return true;
}
}
}

0 comments on commit 872197c

Please sign in to comment.