Browse Source

Version to v0.10: added support for Extra mode's {} special attributes for links and images (id, class, name-value pairs). Updated theme to support 'img.shadowed' which is usable through special attributes. Figure images are always shadowed. Fixed some horrible code formatting from old markdown code.

tags/v0.10
Frans Bouma 10 years ago
parent
commit
9eeef2868f
9 changed files with 257 additions and 121 deletions
  1. +3
    -2
      Themes/Default/Destination/css/theme.css
  2. +2
    -2
      src/DocNet/Properties/AssemblyInfo.cs
  3. +74
    -42
      src/MarkdownDeep/LinkDefinition.cs
  4. +27
    -5
      src/MarkdownDeep/LinkInfo.cs
  5. +1
    -1
      src/MarkdownDeep/MardownDeep.cs
  6. +29
    -20
      src/MarkdownDeep/SpanFormatter.cs
  7. +44
    -0
      src/MarkdownDeep/Utils.cs
  8. +59
    -31
      src/MarkdownDeepTests/LinkAndImgTests.cs
  9. +18
    -18
      src/MarkdownDeepTests/LinkDefinitionTests.cs

+ 3
- 2
Themes/Default/Destination/css/theme.css View File

@@ -324,9 +324,9 @@ img {
border: 0; border: 0;
-ms-interpolation-mode: bicubic; -ms-interpolation-mode: bicubic;
vertical-align: middle; vertical-align: middle;
box-shadow: 0px 0px 10px rgba(10,10,10,0.3);
} }



input { input {
line-height: normal; line-height: normal;
font-size: 100%; font-size: 100%;
@@ -476,8 +476,9 @@ div.figure {
text-align: center; text-align: center;
} }


div.figure img {
img.shadowed, div.figure img {
margin: 0 auto; margin: 0 auto;
box-shadow: 0px 0px 10px rgba(10,10,10,0.3);
} }


div.figure p { div.figure p {


+ 2
- 2
src/DocNet/Properties/AssemblyInfo.cs View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.2.0")]
[assembly: AssemblyFileVersion("0.9.2")]
[assembly: AssemblyVersion("0.10.0.0")]
[assembly: AssemblyFileVersion("0.10.0")]

+ 74
- 42
src/MarkdownDeep/LinkDefinition.cs View File

@@ -21,54 +21,33 @@ namespace MarkdownDeep
{ {
public class LinkDefinition public class LinkDefinition
{ {
public LinkDefinition(string id)
public LinkDefinition(string id) : this(id, string.Empty, string.Empty)
{ {
this.id= id;
} }


public LinkDefinition(string id, string url)
public LinkDefinition(string id, string url) : this(id, url, string.Empty)
{ {
this.id = id;
this.url = url;
} }


public LinkDefinition(string id, string url, string title) public LinkDefinition(string id, string url, string title)
{ {
this.id = id;
this.url = url;
this.title = title;
}

public string id
{
get;
set;
}

public string url
{
get;
set;
}

public string title
{
get;
set;
this.Id = id;
this.Url = url;
this.Title = title;
} }




internal void RenderLink(Markdown m, StringBuilder b, string link_text)
internal void RenderLink(Markdown m, StringBuilder b, string link_text, List<string> specialAttributes)
{ {
if (url.StartsWith("mailto:"))
if (this.Url.StartsWith("mailto:"))
{ {
b.Append("<a href=\""); b.Append("<a href=\"");
Utils.HtmlRandomize(b, url);
Utils.HtmlRandomize(b, this.Url);
b.Append('\"'); b.Append('\"');
if (!String.IsNullOrEmpty(title))
if (!String.IsNullOrEmpty(this.Title))
{ {
b.Append(" title=\""); b.Append(" title=\"");
Utils.SmartHtmlEncodeAmpsAndAngles(b, title);
Utils.SmartHtmlEncodeAmpsAndAngles(b, this.Title);
b.Append('\"'); b.Append('\"');
} }
b.Append('>'); b.Append('>');
@@ -81,17 +60,22 @@ namespace MarkdownDeep


// encode url // encode url
StringBuilder sb = m.GetStringBuilder(); StringBuilder sb = m.GetStringBuilder();
Utils.SmartHtmlEncodeAmpsAndAngles(sb, url);
Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Url);
tag.attributes["href"] = sb.ToString(); tag.attributes["href"] = sb.ToString();


// encode title // encode title
if (!String.IsNullOrEmpty(title ))
if (!String.IsNullOrEmpty(this.Title ))
{ {
sb.Length = 0; sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, title);
Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Title);
tag.attributes["title"] = sb.ToString(); tag.attributes["title"] = sb.ToString();
} }


if(specialAttributes.Any())
{
LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag);
}

// Do user processing // Do user processing
m.OnPrepareLink(tag); m.OnPrepareLink(tag);


@@ -103,13 +87,14 @@ namespace MarkdownDeep
} }
} }


internal void RenderImg(Markdown m, StringBuilder b, string alt_text)

internal void RenderImg(Markdown m, StringBuilder b, string alt_text, List<string> specialAttributes)
{ {
HtmlTag tag = new HtmlTag("img"); HtmlTag tag = new HtmlTag("img");


// encode url // encode url
StringBuilder sb = m.GetStringBuilder(); StringBuilder sb = m.GetStringBuilder();
Utils.SmartHtmlEncodeAmpsAndAngles(sb, url);
Utils.SmartHtmlEncodeAmpsAndAngles(sb, Url);
tag.attributes["src"] = sb.ToString(); tag.attributes["src"] = sb.ToString();


// encode alt text // encode alt text
@@ -121,13 +106,16 @@ namespace MarkdownDeep
} }


// encode title // encode title
if (!String.IsNullOrEmpty(title))
if (!String.IsNullOrEmpty(Title))
{ {
sb.Length = 0; sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, title);
Utils.SmartHtmlEncodeAmpsAndAngles(sb, Title);
tag.attributes["title"] = sb.ToString(); tag.attributes["title"] = sb.ToString();
} }

if(specialAttributes.Any())
{
LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag);
}
tag.closed = true; tag.closed = true;


m.OnPrepareImage(tag, m.RenderingTitledImage); m.OnPrepareImage(tag, m.RenderingTitledImage);
@@ -220,7 +208,7 @@ namespace MarkdownDeep
return null; return null;


// Unescape it // Unescape it
r.url = Utils.UnescapeString(url.Trim(), ExtraMode);
r.Url = Utils.UnescapeString(url.Trim(), ExtraMode);
} }
else else
{ {
@@ -247,7 +235,7 @@ namespace MarkdownDeep
p.SkipEscapableChar(ExtraMode); p.SkipEscapableChar(ExtraMode);
} }


r.url = Utils.UnescapeString(p.Extract().Trim(), ExtraMode);
r.Url = Utils.UnescapeString(p.Extract().Trim(), ExtraMode);
} }


p.SkipLinespace(); p.SkipLinespace();
@@ -329,7 +317,7 @@ namespace MarkdownDeep
} }


// Store the title // Store the title
r.title = Utils.UnescapeString(p.Extract(), ExtraMode);
r.Title = Utils.UnescapeString(p.Extract(), ExtraMode);


// Skip closing quote // Skip closing quote
p.SkipForward(1); p.SkipForward(1);
@@ -337,5 +325,49 @@ namespace MarkdownDeep
// Done! // Done!
return r; return r;
} }


private static void HandleSpecialAttributes(List<string> specialAttributes, StringBuilder sb, HtmlTag tag)
{
string id = specialAttributes.FirstOrDefault(s => s.StartsWith("#"));
if(id != null && id.Length > 1)
{
sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, id.Substring(1));
tag.attributes["id"] = sb.ToString();
}
var cssClasses = new List<string>();
foreach(var cssClass in specialAttributes.Where(s => s.StartsWith(".") && s.Length > 1))
{
sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, cssClass.Substring(1));
cssClasses.Add(sb.ToString());
}
if(cssClasses.Any())
{
tag.attributes["class"] = string.Join(" ", cssClasses.ToArray());
}
foreach(var nameValuePair in specialAttributes.Where(s => s.Contains("=") && s.Length > 2 && !s.StartsWith(".") && !s.StartsWith("#")))
{
var pair = nameValuePair.Split('=');
if(pair.Length == 2)
{
sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[0]);
var key = sb.ToString();
sb.Length = 0;
Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[1]);
var value = sb.ToString();
tag.attributes[key] = value;
}
}
}


#region Properties
public string Id { get; set; }
public string Url { get; set; }
public string Title { get; set; }
#endregion
} }
} }

+ 27
- 5
src/MarkdownDeep/LinkInfo.cs View File

@@ -21,14 +21,36 @@ namespace MarkdownDeep
{ {
internal class LinkInfo internal class LinkInfo
{ {
public LinkInfo(LinkDefinition def, string link_text)
public LinkInfo(LinkDefinition def, string link_text, List<string> specialAttributes )
{ {
this.def = def;
this.link_text = link_text;
this.Definition = def;
this.LinkText = link_text;
this.SpecialAttributes = new List<string>();
if(specialAttributes != null)
{
this.SpecialAttributes.AddRange(specialAttributes);
}
} }


public LinkDefinition def;
public string link_text;

public void RenderLink(Markdown m, StringBuilder sb)
{
var sf = new SpanFormatter(m);
sf.DisableLinks = true;
this.Definition.RenderLink(m, sb, sf.Format(this.LinkText), this.SpecialAttributes);
}


public void RenderImage(Markdown m, StringBuilder sb)
{
this.Definition.RenderImg(m, sb, this.LinkText, this.SpecialAttributes);
}


public LinkDefinition Definition { get; set; }
public string LinkText { get; set; }
public List<string> SpecialAttributes { get; private set; }

} }


} }

+ 1
- 1
src/MarkdownDeep/MardownDeep.cs View File

@@ -568,7 +568,7 @@ namespace MarkdownDeep
internal void AddLinkDefinition(LinkDefinition link) internal void AddLinkDefinition(LinkDefinition link)
{ {
// Store it // Store it
m_LinkDefinitions[link.id]=link;
m_LinkDefinitions[link.Id]=link;
} }


internal void AddFootnote(Block footnote) internal void AddFootnote(Block footnote)


+ 29
- 20
src/MarkdownDeep/SpanFormatter.cs View File

@@ -38,7 +38,7 @@ namespace MarkdownDeep
// If the image is a titled image and there's a class defined for titled images, we'll render it using special markup, otherwise we'll render // If the image is a titled image and there's a class defined for titled images, we'll render it using special markup, otherwise we'll render
// the image as-is. // the image as-is.
if (m_Tokens.Count == 1 && !string.IsNullOrWhiteSpace(m_Markdown.HtmlClassTitledImages) && m_Tokens[0].type == TokenType.img && if (m_Tokens.Count == 1 && !string.IsNullOrWhiteSpace(m_Markdown.HtmlClassTitledImages) && m_Tokens[0].type == TokenType.img &&
m_Tokens[0].data is LinkInfo && !string.IsNullOrWhiteSpace(((LinkInfo)m_Tokens[0].data).def.title))
m_Tokens[0].data is LinkInfo && !string.IsNullOrWhiteSpace(((LinkInfo)m_Tokens[0].data).Definition.Title))
{ {
// Grab the link info // Grab the link info
LinkInfo li = (LinkInfo)m_Tokens[0].data; LinkInfo li = (LinkInfo)m_Tokens[0].data;
@@ -55,10 +55,10 @@ namespace MarkdownDeep
dest.Append("\n"); dest.Append("\n");


// Render the title // Render the title
if (!String.IsNullOrEmpty(li.def.title))
if (!String.IsNullOrEmpty(li.Definition.Title))
{ {
dest.Append("<p>"); dest.Append("<p>");
Utils.SmartHtmlEncodeAmpsAndAngles(dest, li.def.title);
Utils.SmartHtmlEncodeAmpsAndAngles(dest, li.Definition.Title);
dest.Append("</p>\n"); dest.Append("</p>\n");
} }
@@ -128,7 +128,7 @@ namespace MarkdownDeep


case TokenType.link: case TokenType.link:
LinkInfo li = (LinkInfo)t.data; LinkInfo li = (LinkInfo)t.data;
sb.Append(li.link_text);
sb.Append(li.LinkText);
break; break;
} }


@@ -222,17 +222,14 @@ namespace MarkdownDeep
case TokenType.link: case TokenType.link:
{ {
LinkInfo li = (LinkInfo)t.data; LinkInfo li = (LinkInfo)t.data;
var sf = new SpanFormatter(m_Markdown);
sf.DisableLinks = true;

li.def.RenderLink(m_Markdown, sb, sf.Format(li.link_text));
li.RenderLink(m_Markdown, sb);
break; break;
} }


case TokenType.img: case TokenType.img:
{ {
LinkInfo li = (LinkInfo)t.data; LinkInfo li = (LinkInfo)t.data;
li.def.RenderImg(m_Markdown, sb, li.link_text);
li.RenderImage(m_Markdown, sb);
break; break;
} }


@@ -312,14 +309,14 @@ namespace MarkdownDeep
case TokenType.link: case TokenType.link:
{ {
LinkInfo li = (LinkInfo)t.data; LinkInfo li = (LinkInfo)t.data;
sb.Append(li.link_text);
sb.Append(li.LinkText);
break; break;
} }


case TokenType.img: case TokenType.img:
{ {
LinkInfo li = (LinkInfo)t.data; LinkInfo li = (LinkInfo)t.data;
sb.Append(li.link_text);
sb.Append(li.LinkText);
break; break;
} }


@@ -922,11 +919,11 @@ namespace MarkdownDeep
url = "mailto:" + url; url = "mailto:" + url;
} }


li = new LinkInfo(new LinkDefinition("auto", url, null), link_text);
li = new LinkInfo(new LinkDefinition("auto", url, null), link_text, null);
} }
else if (Utils.IsWebAddress(url)) else if (Utils.IsWebAddress(url))
{ {
li=new LinkInfo(new LinkDefinition("auto", url, null), url);
li=new LinkInfo(new LinkDefinition("auto", url, null), url, null);
} }


if (li!=null) if (li!=null)
@@ -981,7 +978,7 @@ namespace MarkdownDeep
if (DisableLinks && token_type==TokenType.link) if (DisableLinks && token_type==TokenType.link)
return null; return null;


bool ExtraMode = m_Markdown.ExtraMode;
bool extraMode = m_Markdown.ExtraMode;


// Find the closing square bracket, allowing for nesting, watching for // Find the closing square bracket, allowing for nesting, watching for
// escapable characters // escapable characters
@@ -1001,7 +998,7 @@ namespace MarkdownDeep
break; break;
} }


this.SkipEscapableChar(ExtraMode);
this.SkipEscapableChar(extraMode);
} }


// Quit if end // Quit if end
@@ -1009,7 +1006,7 @@ namespace MarkdownDeep
return null; return null;


// Get the link text and unescape it // Get the link text and unescape it
string link_text = Utils.UnescapeString(Extract(), ExtraMode);
string link_text = Utils.UnescapeString(Extract(), extraMode);


// The closing ']' // The closing ']'
SkipForward(1); SkipForward(1);
@@ -1030,8 +1027,19 @@ namespace MarkdownDeep
if (!SkipChar(')')) if (!SkipChar(')'))
return null; return null;


List<string> specialAttributes = null;
if(extraMode && DoesMatch('{'))
{
int end;
specialAttributes = Utils.StripSpecialAttributes(this.Input, this.Position, out end);
if(specialAttributes != null)
{
Position = end;
}
}

// Create the token // Create the token
return CreateToken(token_type, new LinkInfo(link_def, link_text));
return CreateToken(token_type, new LinkInfo(link_def, link_text, specialAttributes));
} }


// Optional space or tab // Optional space or tab
@@ -1091,8 +1099,9 @@ namespace MarkdownDeep
if (def == null) if (def == null)
return null; return null;


// Create a token
return CreateToken(token_type, new LinkInfo(def, link_text));
// Create a token.
// [FB]: Currently not supported: special attributes on reference links.
return CreateToken(token_type, new LinkInfo(def, link_text, null));
} }


// Process a ``` code span ``` // Process a ``` code span ```
@@ -1175,7 +1184,7 @@ namespace MarkdownDeep


#endregion #endregion


Markdown m_Markdown;
private Markdown m_Markdown;
internal bool DisableLinks; internal bool DisableLinks;
List<Token> m_Tokens=new List<Token>(); List<Token> m_Tokens=new List<Token>();
} }


+ 44
- 0
src/MarkdownDeep/Utils.cs View File

@@ -486,6 +486,50 @@ namespace MarkdownDeep
return strID; return strID;
} }



/// <summary>
/// Strips the special attributes specified at the location of start. Special attributes are a php markdown extension
/// and specified between {}. Attributes are separated with spaces. It recognizes the following attributes:
/// id, which start with a '#'. Only the first one is used
/// css classes, which start with a'.'. All specified are used
/// name=value pairs, which will end up as attributes on the element.
/// </summary>
/// <param name="str">The string we're scanning.</param>
/// <param name="start">The start (current) position.</param>
/// <param name="end">The end position. Is only valid if returned list contains at least one value.</param>
/// <returns>list of special attributes found, or null if none found or error in string format.</returns>
public static List<string> StripSpecialAttributes(string str, int start, out int end)
{
end = start;
var scanner = new StringScanner(str, start);
if(!scanner.DoesMatch('{'))
{
// not a start of a special attribute block
return null;
}
// first find the end of the block,
scanner.SkipForward(1);
var startOfAttributes = scanner.Position;
// first find the next EOL, as the closing } has to be on this line.
scanner.SkipToEol();
var nextEolPos = scanner.Position;
scanner.Position = startOfAttributes;
scanner.Mark();
if(!scanner.Find('}') || scanner.Position >= nextEolPos)
{
// not enclosed properly.
return null;
}
var attributesString = scanner.Extract();
if(string.IsNullOrWhiteSpace(attributesString))
{
return null;
}
// Position is on enclosing '}' (due to the Find('}'), so we have to skip 1 character
end = scanner.Position + 1;
return attributesString.Split(' ').Where(s=>!string.IsNullOrWhiteSpace(s)).ToList();
}

public static bool IsUrlFullyQualified(string url) public static bool IsUrlFullyQualified(string url)
{ {
return url.Contains("://") || url.StartsWith("mailto:"); return url.Contains("://") || url.StartsWith("mailto:");


+ 59
- 31
src/MarkdownDeepTests/LinkAndImgTests.cs View File

@@ -10,85 +10,104 @@ namespace MarkdownDeepTests
[TestFixture] [TestFixture]
class LinkAndImgTests class LinkAndImgTests
{ {
SpanFormatter _formatter;


[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
m = new Markdown();
m.AddLinkDefinition(new LinkDefinition("link1", "url.com", "title"));
m.AddLinkDefinition(new LinkDefinition("link2", "url.com"));
m.AddLinkDefinition(new LinkDefinition("img1", "url.com/image.png", "title"));
m.AddLinkDefinition(new LinkDefinition("img2", "url.com/image.png"));
_formatter = new SpanFormatter(GetSetupMarkdown());
}


[Test]
public void InlineLinkWithoutTitleWithSpecialAttributes()
{
var m = GetSetupMarkdown();
m.ExtraMode = true;
var s = new SpanFormatter(m);
Assert.AreEqual("pre <a href=\"url.com\" id=\"foo\" class=\"a b cl\" lang=\"nl\">link text</a> post",
s.Format("pre [link text](url.com){#foo .a .b .cl lang=nl} post"));
}


s = new SpanFormatter(m);

[Test]
public void InlineImgWithoutTitleWithSpecialAttributes()
{
var m = GetSetupMarkdown();
m.ExtraMode = true;
var s = new SpanFormatter(m);
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" id=\"foo\" class=\"a b cl\" lang=\"nl\" /> post",
s.Format("pre ![alt text](url.com/image.png){#foo .a .b .cl lang=nl} post"));
} }


[Test] [Test]
public void ReferenceLinkWithTitle() public void ReferenceLinkWithTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post", Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post",
s.Format("pre [link text][link1] post"));
_formatter.Format("pre [link text][link1] post"));
} }


[Test] [Test]
public void ReferenceLinkIdsAreCaseInsensitive() public void ReferenceLinkIdsAreCaseInsensitive()
{ {
Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post", Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post",
s.Format("pre [link text][LINK1] post"));
_formatter.Format("pre [link text][LINK1] post"));
} }


[Test] [Test]
public void ImplicitReferenceLinkWithoutTitle() public void ImplicitReferenceLinkWithoutTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\">link2</a> post", Assert.AreEqual("pre <a href=\"url.com\">link2</a> post",
s.Format("pre [link2] post"));
_formatter.Format("pre [link2] post"));
Assert.AreEqual("pre <a href=\"url.com\">link2</a> post", Assert.AreEqual("pre <a href=\"url.com\">link2</a> post",
s.Format("pre [link2][] post"));
_formatter.Format("pre [link2][] post"));
} }


[Test] [Test]
public void ImplicitReferenceLinkWithTitle() public void ImplicitReferenceLinkWithTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link1</a> post", Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link1</a> post",
s.Format("pre [link1] post"));
_formatter.Format("pre [link1] post"));
Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link1</a> post", Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link1</a> post",
s.Format("pre [link1][] post"));
_formatter.Format("pre [link1][] post"));
} }


[Test] [Test]
public void ReferenceLinkWithoutTitle() public void ReferenceLinkWithoutTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\">link text</a> post", Assert.AreEqual("pre <a href=\"url.com\">link text</a> post",
s.Format("pre [link text][link2] post"));
_formatter.Format("pre [link text][link2] post"));
} }


[Test] [Test]
public void MissingReferenceLink() public void MissingReferenceLink()
{ {
Assert.AreEqual("pre [link text][missing] post", Assert.AreEqual("pre [link text][missing] post",
s.Format("pre [link text][missing] post"));
_formatter.Format("pre [link text][missing] post"));
} }


[Test] [Test]
public void InlineLinkWithTitle() public void InlineLinkWithTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post", Assert.AreEqual("pre <a href=\"url.com\" title=\"title\">link text</a> post",
s.Format("pre [link text](url.com \"title\") post"));
_formatter.Format("pre [link text](url.com \"title\") post"));
} }


[Test] [Test]
public void InlineLinkWithoutTitle() public void InlineLinkWithoutTitle()
{ {
Assert.AreEqual("pre <a href=\"url.com\">link text</a> post", Assert.AreEqual("pre <a href=\"url.com\">link text</a> post",
s.Format("pre [link text](url.com) post"));
_formatter.Format("pre [link text](url.com) post"));
} }


[Test] [Test]
public void Boundaries() public void Boundaries()
{ {
Assert.AreEqual("<a href=\"url.com\">link text</a>", Assert.AreEqual("<a href=\"url.com\">link text</a>",
s.Format("[link text](url.com)"));
_formatter.Format("[link text](url.com)"));
Assert.AreEqual("<a href=\"url.com\" title=\"title\">link text</a>", Assert.AreEqual("<a href=\"url.com\" title=\"title\">link text</a>",
s.Format("[link text][link1]"));
_formatter.Format("[link text][link1]"));
} }




@@ -96,53 +115,53 @@ namespace MarkdownDeepTests
public void ReferenceImgWithTitle() public void ReferenceImgWithTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" title=\"title\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" title=\"title\" /> post",
s.Format("pre ![alt text][img1] post"));
_formatter.Format("pre ![alt text][img1] post"));
} }


[Test] [Test]
public void ImplicitReferenceImgWithoutTitle() public void ImplicitReferenceImgWithoutTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img2\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img2\" /> post",
s.Format("pre ![img2] post"));
_formatter.Format("pre ![img2] post"));
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img2\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img2\" /> post",
s.Format("pre ![img2][] post"));
_formatter.Format("pre ![img2][] post"));
} }


[Test] [Test]
public void ImplicitReferenceImgWithTitle() public void ImplicitReferenceImgWithTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img1\" title=\"title\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img1\" title=\"title\" /> post",
s.Format("pre ![img1] post"));
_formatter.Format("pre ![img1] post"));
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img1\" title=\"title\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"img1\" title=\"title\" /> post",
s.Format("pre ![img1][] post"));
_formatter.Format("pre ![img1][] post"));
} }


[Test] [Test]
public void ReferenceImgWithoutTitle() public void ReferenceImgWithoutTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" /> post",
s.Format("pre ![alt text][img2] post"));
_formatter.Format("pre ![alt text][img2] post"));
} }


[Test] [Test]
public void MissingReferenceImg() public void MissingReferenceImg()
{ {
Assert.AreEqual("pre ![alt text][missing] post", Assert.AreEqual("pre ![alt text][missing] post",
s.Format("pre ![alt text][missing] post"));
_formatter.Format("pre ![alt text][missing] post"));
} }


[Test] [Test]
public void InlineImgWithTitle() public void InlineImgWithTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" title=\"title\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" title=\"title\" /> post",
s.Format("pre ![alt text](url.com/image.png \"title\") post"));
_formatter.Format("pre ![alt text](url.com/image.png \"title\") post"));
} }


[Test] [Test]
public void InlineImgWithoutTitle() public void InlineImgWithoutTitle()
{ {
Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" /> post", Assert.AreEqual("pre <img src=\"url.com/image.png\" alt=\"alt text\" /> post",
s.Format("pre ![alt text](url.com/image.png) post"));
_formatter.Format("pre ![alt text](url.com/image.png) post"));
} }




@@ -150,10 +169,19 @@ namespace MarkdownDeepTests
public void ImageLink() public void ImageLink()
{ {
Assert.AreEqual("pre <a href=\"url.com\"><img src=\"url.com/image.png\" alt=\"alt text\" /></a> post", Assert.AreEqual("pre <a href=\"url.com\"><img src=\"url.com/image.png\" alt=\"alt text\" /></a> post",
s.Format("pre [![alt text](url.com/image.png)](url.com) post"));
_formatter.Format("pre [![alt text](url.com/image.png)](url.com) post"));
}



private Markdown GetSetupMarkdown()
{
var toReturn = new Markdown();
toReturn.AddLinkDefinition(new LinkDefinition("link1", "url.com", "title"));
toReturn.AddLinkDefinition(new LinkDefinition("link2", "url.com"));
toReturn.AddLinkDefinition(new LinkDefinition("img1", "url.com/image.png", "title"));
toReturn.AddLinkDefinition(new LinkDefinition("img2", "url.com/image.png"));
return toReturn;
} }
Markdown m;
SpanFormatter s;
} }
} }

+ 18
- 18
src/MarkdownDeepTests/LinkDefinitionTests.cs View File

@@ -23,9 +23,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "url.com");
Assert.AreEqual(r.title, null);
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "url.com");
Assert.AreEqual(r.Title, string.Empty);
} }


[Test] [Test]
@@ -35,9 +35,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "url.com");
Assert.AreEqual(r.title, "my title");
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "url.com");
Assert.AreEqual(r.Title, "my title");
} }


[Test] [Test]
@@ -47,9 +47,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "url.com");
Assert.AreEqual(r.title, "my title");
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "url.com");
Assert.AreEqual(r.Title, "my title");
} }


[Test] [Test]
@@ -59,9 +59,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "url.com");
Assert.AreEqual(r.title, "my title");
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "url.com");
Assert.AreEqual(r.Title, "my title");
} }


[Test] [Test]
@@ -71,9 +71,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "url.com");
Assert.AreEqual(r.title, "my title");
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "url.com");
Assert.AreEqual(r.Title, "my title");
} }


[Test] [Test]
@@ -83,9 +83,9 @@ namespace MarkdownDeepTests
r = LinkDefinition.ParseLinkDefinition(str, false); r = LinkDefinition.ParseLinkDefinition(str, false);


Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(r.id, "id");
Assert.AreEqual(r.url, "http://www.site.com");
Assert.AreEqual(r.title, "my title");
Assert.AreEqual(r.Id, "id");
Assert.AreEqual(r.Url, "http://www.site.com");
Assert.AreEqual(r.Title, "my title");
} }


[Test] [Test]


Loading…
Cancel
Save