Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
52488d8
Render Wrapped Images
avknaidu Apr 3, 2018
ad7df83
Update Logic
avknaidu Apr 18, 2018
6fa00e6
Using RenderURL instead of URL for rendering Images and using URL as …
avknaidu Apr 19, 2018
bf99515
Update Initial Content
avknaidu Apr 19, 2018
1ae2fde
Cleaned up second scenario in initial content
avknaidu Apr 19, 2018
c3a9b16
Placed Escape Character Properly.
avknaidu Apr 23, 2018
b34b7b2
Change Scheme to pick from URI and return directly instead of addl va…
avknaidu Apr 23, 2018
66e363d
changed definition of KnownSchemes to match scheme from URI( Since th…
avknaidu Apr 23, 2018
752d096
Makesure Tooltip is shown on Links
avknaidu Apr 23, 2018
4e06d60
Implementing LinkClicked on Images Wrapped as Links
avknaidu Apr 24, 2018
8194682
Removed unwanted code.
avknaidu Apr 25, 2018
23f6b8b
Merge branch 'master' into TextToolBar
avknaidu May 11, 2018
b518b2c
Adding RenderURL and ReferenceID Properties for Tests.
avknaidu May 14, 2018
2762ad0
Changing Scheme's in Tests
avknaidu May 14, 2018
bd7d721
Public to Internal
avknaidu May 14, 2018
58d1e1c
Merge branch 'TextToolBar' of https://github.com/avknaidu/UWPCommunit…
avknaidu May 14, 2018
1a8a25a
Merge branch 'master' into TextToolBar
avknaidu May 14, 2018
1c64b27
Merge branch 'master' into TextToolBar
nmetulev May 15, 2018
f4036fc
Merge branch 'master' into TextToolBar
avknaidu May 17, 2018
1e4ac02
Merge branch 'master' into TextToolBar
azchohfi May 17, 2018
db6912f
Merge branch 'master' into TextToolBar
nmetulev May 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Microsoft.Toolkit.Parsers/Markdown/Helpers/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -511,5 +511,30 @@ public static int SkipQuoteCharacters(string markdown, int start, int end, int q

return startOfLine;
}

/// <summary>
/// Checks if the given URL is allowed in a markdown link.
/// </summary>
/// <param name="url"> The URL to check. </param>
/// <returns> <c>true</c> if the URL is valid; <c>false</c> otherwise. </returns>
public static bool IsUrlValid(string url)
{
// URLs can be relative.
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri result))
{
return true;
}

// Check the scheme is allowed.
foreach (var scheme in HyperlinkInline.KnownSchemes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can get the scheme directly from the result uri above and just check if the KnownSchemes contains it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
if (result.Scheme.Equals(scheme))
{
return true;
}
}

return false;
}
}
}
22 changes: 11 additions & 11 deletions Microsoft.Toolkit.Parsers/Markdown/Inlines/HyperlinkInline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ internal static void AddTripChars(List<InlineTripCharHelper> tripCharHelpers)
/// </summary>
internal static readonly string[] KnownSchemes = new string[]
{
"http://",
"https://",
"ftp://",
"steam://",
"irc://",
"news://",
"mumble://",
"ssh://",
"ms-windows-store://",
"sip:"
"http",
"https",
"ftp",
"steam",
"irc",
"news",
"mumble",
"ssh",
"ms-windows-store",
"sip"
};

/// <summary>
Expand Down Expand Up @@ -140,7 +140,7 @@ internal static InlineParseResult ParseUrl(string markdown, int tripPos, int max
// Check for a known scheme e.g. "https://".
foreach (var scheme in KnownSchemes)
{
int schemeStart = tripPos - (scheme.Length - 3);
int schemeStart = tripPos - scheme.Length;
if (schemeStart >= 0 && schemeStart <= maxEnd - scheme.Length && string.Equals(markdown.Substring(schemeStart, scheme.Length), scheme, StringComparison.OrdinalIgnoreCase))
{
// URL scheme found.
Expand Down
146 changes: 105 additions & 41 deletions Microsoft.Toolkit.Parsers/Markdown/Inlines/ImageInline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public ImageInline()
/// </summary>
public string Url { get; set; }

/// <summary>
/// Gets or sets the image Render URL.
/// </summary>
public string RenderUrl { get; set; }

/// <summary>
/// Gets or sets a text to display on hover.
/// </summary>
Expand All @@ -44,6 +49,11 @@ public ImageInline()
/// <inheritdoc/>
public string Text { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the ID of a reference, if this is a reference-style link.
/// </summary>
public string ReferenceId { get; set; }

/// <summary>
/// Gets image width
/// If value is greater than 0, ImageStretch is set to UniformToFill
Expand Down Expand Up @@ -72,6 +82,8 @@ internal static void AddTripChars(List<InlineTripCharHelper> tripCharHelpers)
/// <returns> A parsed markdown image, or <c>null</c> if this is not a markdown image. </returns>
internal static InlineParseResult Parse(string markdown, int start, int end)
{
int refstart = 0;

// Expect a '!' character.
if (start >= end || markdown[start] != '!')
{
Expand Down Expand Up @@ -109,68 +121,86 @@ internal static InlineParseResult Parse(string markdown, int start, int end)

// Expect the '(' character.
pos++;
if (pos == end || markdown[pos] != '(')
{
return null;
}

// Skip whitespace
pos++;
while (pos < end && ParseHelpers.IsMarkdownWhiteSpace(markdown[pos]))
{
pos++;
}

if (pos == end)
{
return null;
}
string reference = string.Empty;
string url = string.Empty;
int imageWidth = 0;
int imageHeight = 0;

// Extract the URL.
int urlStart = pos;
while (pos < end && markdown[pos] != ')')
if (pos < end && markdown[pos] == '[')
{
pos++;
}

var imageDimensionsPos = markdown.IndexOf(" =", urlStart, pos - urlStart, StringComparison.Ordinal);
refstart = pos;

var url = imageDimensionsPos > 0
? TextRunInline.ResolveEscapeSequences(markdown, urlStart, imageDimensionsPos)
: TextRunInline.ResolveEscapeSequences(markdown, urlStart, pos);
// Find the reference ']' character
while (pos < end)
{
if (markdown[pos] == ']')
{
break;
}

int imageWidth = 0;
int imageHeight = 0;
pos++;
}

if (imageDimensionsPos > 0)
reference = markdown.Substring(refstart + 1, pos - refstart - 1);
}
else if (pos < end && markdown[pos] == '(')
{
// trying to find 'x' which separates image width and height
var dimensionsSepatorPos = markdown.IndexOf("x", imageDimensionsPos + 2, pos - imageDimensionsPos - 1, StringComparison.Ordinal);

// didn't find separator, trying to parse value as imageWidth
if (dimensionsSepatorPos == -1)
while (pos < end && ParseHelpers.IsMarkdownWhiteSpace(markdown[pos]))
{
var imageWidthStr = markdown.Substring(imageDimensionsPos + 2, pos - imageDimensionsPos - 2);
pos++;
}

int.TryParse(imageWidthStr, out imageWidth);
// Extract the URL.
int urlStart = pos;
while (pos < end && markdown[pos] != ')')
{
pos++;
}
else

var imageDimensionsPos = markdown.IndexOf(" =", urlStart, pos - urlStart, StringComparison.Ordinal);

url = imageDimensionsPos > 0
? TextRunInline.ResolveEscapeSequences(markdown, urlStart + 1, imageDimensionsPos)
: TextRunInline.ResolveEscapeSequences(markdown, urlStart + 1, pos);

if (imageDimensionsPos > 0)
{
var dimensions = markdown.Substring(imageDimensionsPos + 2, pos - imageDimensionsPos - 2).Split('x');
// trying to find 'x' which separates image width and height
var dimensionsSepatorPos = markdown.IndexOf("x", imageDimensionsPos + 2, pos - imageDimensionsPos - 1, StringComparison.Ordinal);

// didn't find separator, trying to parse value as imageWidth
if (dimensionsSepatorPos == -1)
{
var imageWidthStr = markdown.Substring(imageDimensionsPos + 2, pos - imageDimensionsPos - 2);

// got width and height
if (dimensions.Length == 2)
int.TryParse(imageWidthStr, out imageWidth);
}
else
{
int.TryParse(dimensions[0], out imageWidth);
int.TryParse(dimensions[1], out imageHeight);
var dimensions = markdown.Substring(imageDimensionsPos + 2, pos - imageDimensionsPos - 2).Split('x');

// got width and height
if (dimensions.Length == 2)
{
int.TryParse(dimensions[0], out imageWidth);
int.TryParse(dimensions[1], out imageHeight);
}
}
}
}

if (pos == end)
{
return null;
}

// We found something!
var result = new ImageInline
{
Tooltip = tooltip,
RenderUrl = url,
ReferenceId = reference,
Url = url,
Text = markdown.Substring(start, pos + 1 - start),
ImageWidth = imageWidth,
Expand All @@ -179,6 +209,40 @@ internal static InlineParseResult Parse(string markdown, int start, int end)
return new InlineParseResult(result, start, pos + 1);
}

/// <summary>
/// If this is a reference-style link, attempts to converts it to a regular link.
/// </summary>
/// <param name="document"> The document containing the list of references. </param>
internal void ResolveReference(MarkdownDocument document)
{
if (document == null)
{
throw new ArgumentNullException("document");
}

if (ReferenceId == null)
{
return;
}

// Look up the reference ID.
var reference = document.LookUpReference(ReferenceId);
if (reference == null)
{
return;
}

// The reference was found. Check the URL is valid.
if (!Common.IsUrlValid(reference.Url))
{
return;
}

// Everything is cool when you're part of a team.
RenderUrl = reference.Url;
ReferenceId = null;
}

/// <summary>
/// Converts the object into it's textual representation.
/// </summary>
Expand Down
33 changes: 3 additions & 30 deletions Microsoft.Toolkit.Parsers/Markdown/Inlines/MarkdownLinkInline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ internal static InlineParseResult Parse(string markdown, int start, int maxEnd)
// Check the URL is okay.
if (!url.IsEmail())
{
if (!IsUrlValid(url))
if (!Common.IsUrlValid(url))
{
return null;
}
Expand Down Expand Up @@ -243,7 +243,7 @@ internal static InlineParseResult Parse(string markdown, int start, int maxEnd)
/// If this is a reference-style link, attempts to converts it to a regular link.
/// </summary>
/// <param name="document"> The document containing the list of references. </param>
public void ResolveReference(MarkdownDocument document)
internal void ResolveReference(MarkdownDocument document)
{
if (document == null)
{
Expand All @@ -263,7 +263,7 @@ public void ResolveReference(MarkdownDocument document)
}

// The reference was found. Check the URL is valid.
if (!IsUrlValid(reference.Url))
if (!Common.IsUrlValid(reference.Url))
{
return;
}
Expand All @@ -274,33 +274,6 @@ public void ResolveReference(MarkdownDocument document)
ReferenceId = null;
}

/// <summary>
/// Checks if the given URL is allowed in a markdown link.
/// </summary>
/// <param name="url"> The URL to check. </param>
/// <returns> <c>true</c> if the URL is valid; <c>false</c> otherwise. </returns>
private static bool IsUrlValid(string url)
{
// URLs can be relative.
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri result))
{
return true;
}

// Check the scheme is allowed.
bool schemeIsAllowed = false;
foreach (var scheme in HyperlinkInline.KnownSchemes)
{
if (url.StartsWith(scheme))
{
schemeIsAllowed = true;
break;
}
}

return schemeIsAllowed;
}

/// <summary>
/// Converts the object into it's textual representation.
/// </summary>
Expand Down
20 changes: 17 additions & 3 deletions Microsoft.Toolkit.Parsers/Markdown/Render/MarkdownRendererBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,26 @@ protected void CheckRenderMarkdownLink(MarkdownLinkInline element, IRenderContex
{
// The element couldn't be resolved, just render it as text.
RenderInlineChildren(element.Inlines, context);
return;
}
else

foreach (MarkdownInline inline in element.Inlines)
{
// Url is valid, create Link.
RenderMarkdownLink(element, context);
if (inline is ImageInline imageInline)
{
// this is an image, create Image.
if (!string.IsNullOrEmpty(imageInline.ReferenceId))
{
imageInline.ResolveReference(Document);
}

imageInline.Url = element.Url;
RenderImage(imageInline, context);
return;
}
}

RenderMarkdownLink(element, context);
}

/// <summary>
Expand Down
Loading