mirror of
https://github.com/xoofx/markdig.git
synced 2026-10-08 06:38:39 +00:00
Move helper classes to Helpers namespace. Regroup methods in helpers
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Syntax;
|
||||
|
||||
namespace Textamina.Markdig.Formatters
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using Textamina.Markdig.Helpers;
|
||||
|
||||
namespace Textamina.Markdig.Formatters
|
||||
{
|
||||
|
||||
@@ -1,461 +0,0 @@
|
||||
using System;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Formatters
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Contains the regular expressions that are used in the parsers.
|
||||
/// </summary>
|
||||
internal static partial class Scanner
|
||||
{
|
||||
/// <summary>
|
||||
/// List of valid schemes of an URL. The array must be sorted.
|
||||
/// </summary>
|
||||
private static readonly string[] schemeArray = new[]
|
||||
{
|
||||
"AAA", "AAAS", "ABOUT", "ACAP", "ADIUMXTRA", "AFP", "AFS", "AIM", "APT", "ATTACHMENT", "AW", "BESHARE",
|
||||
"BITCOIN", "BOLO", "CALLTO", "CAP", "CHROME", "CHROME-EXTENSION", "CID", "COAP", "COM-EVENTBRITE-ATTENDEE",
|
||||
"CONTENT", "CRID", "CVS", "DATA", "DAV", "DICT", "DLNA-PLAYCONTAINER", "DLNA-PLAYSINGLE", "DNS", "DOI",
|
||||
"DTN", "DVB", "ED2K", "FACETIME", "FEED", "FILE", "FINGER", "FISH", "FTP", "GEO", "GG", "GIT",
|
||||
"GIZMOPROJECT", "GO", "GOPHER", "GTALK", "H323", "HCP", "HTTP", "HTTPS", "IAX", "ICAP", "ICON", "IM", "IMAP",
|
||||
"INFO", "IPN", "IPP", "IRC", "IRC6", "IRCS", "IRIS", "IRIS.BEEP", "IRIS.LWZ", "IRIS.XPC", "IRIS.XPCS",
|
||||
"ITMS", "JAR", "JAVASCRIPT", "JMS", "KEYPARC", "LASTFM", "LDAP", "LDAPS", "MAGNET", "MAILTO", "MAPS",
|
||||
"MARKET", "MESSAGE", "MID", "MMS", "MS-HELP", "MSNIM", "MSRP", "MSRPS", "MTQP", "MUMBLE", "MUPDATE", "MVN",
|
||||
"NEWS", "NFS", "NI", "NIH", "NNTP", "NOTES", "OID", "OPAQUELOCKTOKEN", "PALM", "PAPARAZZI", "PLATFORM",
|
||||
"POP", "PRES", "PROXY", "PSYC", "QUERY", "RES", "RESOURCE", "RMI", "RSYNC", "RTMP", "RTSP", "SECONDLIFE",
|
||||
"SERVICE", "SESSION", "SFTP", "SGN", "SHTTP", "SIEVE", "SIP", "SIPS", "SKYPE", "SMB", "SMS", "SNMP",
|
||||
"SOAP.BEEP", "SOAP.BEEPS", "SOLDAT", "SPOTIFY", "SSH", "STEAM", "SVN", "TAG", "TEAMSPEAK", "TEL", "TELNET",
|
||||
"TFTP", "THINGS", "THISMESSAGE", "TIP", "TN3270", "TV", "UDP", "UNREAL", "URN", "UT2004", "VEMMI",
|
||||
"VENTRILO", "VIEW-SOURCE", "WEBCAL", "WS", "WSS", "WTAI", "WYCIWYG", "XCON", "XCON-USERID", "XFIRE",
|
||||
"XMLRPC.BEEP", "XMLRPC.BEEPS", "XMPP", "XRI", "YMSGR", "Z39.50R", "Z39.50S"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Try to match URI autolink after first <, returning number of chars matched.
|
||||
/// </summary>
|
||||
public static int scan_autolink_uri(string s, int pos, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>] { return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
// for now the tests do not include anything that would require the use of `escaped_char` part so it is ignored.
|
||||
|
||||
// 24 is the maximum length of a valid scheme
|
||||
var checkLen = sourceLength - pos;
|
||||
if (checkLen > 24)
|
||||
checkLen = 24;
|
||||
|
||||
// PERF: potential small improvement - instead of using IndexOf, check char-by-char and return as soon as an invalid character is found ([^a-z0-9\.])
|
||||
// alternative approach (if we want to go crazy about performance - store the valid schemes as a prefix tree and lookup the valid scheme char by char and
|
||||
// return as soon as the part does not match any prefix.
|
||||
var colonpos = s.IndexOf(':', pos, checkLen);
|
||||
if (colonpos == -1)
|
||||
return 0;
|
||||
|
||||
var potentialScheme = s.Substring(pos, colonpos - pos).ToUpperInvariant();
|
||||
if (Array.BinarySearch(schemeArray, potentialScheme, StringComparer.Ordinal) < 0)
|
||||
return 0;
|
||||
|
||||
for (var i = colonpos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
if (c == '>')
|
||||
return i - pos + 1;
|
||||
|
||||
if (c == '<' || c <= 0x20)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to match a link title (in single quotes, in double quotes, or
|
||||
/// in parentheses), returning number of chars matched. Allow one
|
||||
/// level of internal nesting (quotes within quotes).
|
||||
/// </summary>
|
||||
public static int scan_link_title(string s, int pos, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
["] (escaped_char|[^"\x00])* ["] { return (p - start); }
|
||||
['] (escaped_char|[^'\x00])* ['] { return (p - start); }
|
||||
[(] (escaped_char|[^)\x00])* [)] { return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
if (pos + 2 >= sourceLength)
|
||||
return 0;
|
||||
|
||||
var c1 = s[pos];
|
||||
if (c1 != '"' && c1 != '\'' && c1 != '(')
|
||||
return 0;
|
||||
|
||||
if (c1 == '(') c1 = ')';
|
||||
|
||||
var nextEscaped = false;
|
||||
for (var i = pos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
if (c == c1 && !nextEscaped)
|
||||
return i - pos + 1;
|
||||
|
||||
nextEscaped = !nextEscaped && c == '\\';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Match space characters, including newlines.
|
||||
/// </summary>
|
||||
public static int scan_spacechars(string s, int pos, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
[ \t\n]* { return (p - start); }
|
||||
. { return 0; }
|
||||
*/
|
||||
if (pos >= sourceLength)
|
||||
return 0;
|
||||
|
||||
for (var i = pos; i < sourceLength; i++)
|
||||
{
|
||||
if (!Utility.IsWhitespace(s[i]))
|
||||
return i - pos;
|
||||
}
|
||||
|
||||
return sourceLength - pos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Match ATX heading start.
|
||||
/// </summary>
|
||||
public static int scan_atx_heading_start(string s, int pos, int sourceLength, out int headingLevel)
|
||||
{
|
||||
/*!re2c
|
||||
[#]{1,6} ([ ]+|[\n]) { return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
headingLevel = 1;
|
||||
if (pos + 1 >= sourceLength)
|
||||
return 0;
|
||||
|
||||
if (s[pos] != '#')
|
||||
return 0;
|
||||
|
||||
var spaceExists = false;
|
||||
for (var i = pos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
|
||||
if (c == '#')
|
||||
{
|
||||
if (headingLevel == 6)
|
||||
return 0;
|
||||
|
||||
if (spaceExists)
|
||||
return i - pos;
|
||||
else
|
||||
headingLevel++;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
spaceExists = true;
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
return i - pos + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return spaceExists ? i - pos : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (spaceExists)
|
||||
return sourceLength - pos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Match sexext heading line. Return 1 for level-1 heading,
|
||||
/// 2 for level-2, 0 for no match.
|
||||
/// </summary>
|
||||
public static int scan_setext_heading_line(string s, int pos, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
[=]+ [ ]* [\n] { return 1; }
|
||||
[-]+ [ ]* [\n] { return 2; }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
if (pos >= sourceLength)
|
||||
return 0;
|
||||
|
||||
var c1 = s[pos];
|
||||
|
||||
if (c1 != '=' && c1 != '-')
|
||||
return 0;
|
||||
|
||||
var fin = false;
|
||||
for (var i = pos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
if (c == c1 && !fin)
|
||||
continue;
|
||||
|
||||
fin = true;
|
||||
if (c == ' ')
|
||||
continue;
|
||||
|
||||
if (c == '\n')
|
||||
break;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return c1 == '=' ? 1 : 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan a thematic break line: "...three or more hyphens, asterisks,
|
||||
/// or underscores on a line by themselves. If you wish, you may use
|
||||
/// spaces between the hyphens or asterisks."
|
||||
/// </summary>
|
||||
public static int scan_thematic_break(string s, int pos, int sourceLength)
|
||||
{
|
||||
// @"^([\*][ ]*){3,}[\s]*$",
|
||||
// @"^([_][ ]*){3,}[\s]*$",
|
||||
// @"^([-][ ]*){3,}[\s]*$",
|
||||
|
||||
var count = 0;
|
||||
var x = '\0';
|
||||
var ipos = pos;
|
||||
while (ipos < sourceLength)
|
||||
{
|
||||
var c = s[ipos++];
|
||||
|
||||
if (c == ' ' || c == '\n')
|
||||
continue;
|
||||
if (count == 0)
|
||||
{
|
||||
if (c == '*' || c == '_' || c == '-')
|
||||
x = c;
|
||||
else
|
||||
return 0;
|
||||
|
||||
count = 1;
|
||||
}
|
||||
else if (c == x)
|
||||
count++;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (count < 3)
|
||||
return 0;
|
||||
|
||||
return sourceLength - pos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan an opening code fence. Returns the number of characters forming the fence.
|
||||
/// </summary>
|
||||
public static int scan_open_code_fence(string s, int pos, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
[`]{3,} / [^`\n\x00]*[\n] { return (p - start); }
|
||||
[~]{3,} / [^~\n\x00]*[\n] { return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
if (pos + 3 >= sourceLength)
|
||||
return 0;
|
||||
|
||||
var fchar = s[pos];
|
||||
if (fchar != '`' && fchar != '~')
|
||||
return 0;
|
||||
|
||||
var cnt = 1;
|
||||
var fenceDone = false;
|
||||
for (var i = pos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
|
||||
if (c == fchar)
|
||||
{
|
||||
if (fenceDone)
|
||||
return 0;
|
||||
|
||||
cnt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
fenceDone = true;
|
||||
if (cnt < 3)
|
||||
return 0;
|
||||
|
||||
if (c == '\n')
|
||||
return cnt;
|
||||
}
|
||||
|
||||
if (cnt < 3)
|
||||
return 0;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan a closing code fence with length at least len.
|
||||
/// </summary>
|
||||
public static int scan_close_code_fence(string s, int pos, int len, int sourceLength)
|
||||
{
|
||||
/*!re2c
|
||||
([`]{3,} | [~]{3,}) / spacechar* [\n]
|
||||
{ if (p - start > len) {
|
||||
return (p - start);
|
||||
} else {
|
||||
return 0;
|
||||
} }
|
||||
.? { return 0; }
|
||||
*/
|
||||
if (pos + len >= sourceLength)
|
||||
return 0;
|
||||
|
||||
var c1 = s[pos];
|
||||
if (c1 != '`' && c1 != '~')
|
||||
return 0;
|
||||
|
||||
var cnt = 1;
|
||||
var spaces = false;
|
||||
for (var i = pos + 1; i < sourceLength; i++)
|
||||
{
|
||||
var c = s[i];
|
||||
if (c == c1 && !spaces)
|
||||
cnt++;
|
||||
else if (c == ' ')
|
||||
spaces = true;
|
||||
else if (c == '\n')
|
||||
return cnt < len ? 0 : cnt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans an entity.
|
||||
/// Returns number of chars matched.
|
||||
/// </summary>
|
||||
public static int scan_entity(string s, int pos, int length, out string namedEntity, out int numericEntity)
|
||||
{
|
||||
/*!re2c
|
||||
[&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
|
||||
{ return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
var lastPos = pos + length;
|
||||
|
||||
namedEntity = null;
|
||||
numericEntity = 0;
|
||||
|
||||
if (pos + 3 >= lastPos)
|
||||
return 0;
|
||||
|
||||
if (s[pos] != '&')
|
||||
return 0;
|
||||
|
||||
char c;
|
||||
int i;
|
||||
int counter = 0;
|
||||
if (s[pos + 1] == '#')
|
||||
{
|
||||
c = s[pos + 2];
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
// expect 1-8 hex digits starting from pos+3
|
||||
for (i = pos + 3; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - '0');
|
||||
continue;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - 'A' + 10);
|
||||
continue;
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - 'a' + 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// expect 1-8 digits starting from pos+2
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*10 + (c - '0');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// expect a letter and 1-31 letters or digits
|
||||
c = s[pos + 1];
|
||||
if ((c < 'A' || c > 'Z') && (c < 'a' && c > 'z'))
|
||||
return 0;
|
||||
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
||||
{
|
||||
if (++counter == 32)
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
{
|
||||
namedEntity = s.Substring(pos + 1, counter + 1);
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Textamina.Markdig.Parsing
|
||||
namespace Textamina.Markdig.Helpers
|
||||
{
|
||||
internal class Utility
|
||||
public static class CharHelper
|
||||
{
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsWhitespace(char c)
|
||||
public static bool IsWhitespace(this char c)
|
||||
{
|
||||
// 2.1 Characters and lines
|
||||
// A whitespace character is a space(U + 0020), tab(U + 0009), newline(U + 000A), line tabulation (U + 000B), form feed (U + 000C), or carriage return (U + 000D).
|
||||
@@ -13,38 +13,38 @@ namespace Textamina.Markdig.Parsing
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsControl(char c)
|
||||
public static bool IsControl(this char c)
|
||||
{
|
||||
return c < ' ' || char.IsControl(c);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsEscapableSymbol(char c)
|
||||
public static bool IsEscapableSymbol(this char c)
|
||||
{
|
||||
// char.IsSymbol also works with Unicode symbols that cannot be escaped based on the specification.
|
||||
return (c > ' ' && c < '0') || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || (c > 'z' && c < 127) || c == '•';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsWhiteSpaceOrZero(char c)
|
||||
public static bool IsWhiteSpaceOrZero(this char c)
|
||||
{
|
||||
return IsWhitespace(c) || IsZero(c);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsNewLine(char c)
|
||||
public static bool IsNewLine(this char c)
|
||||
{
|
||||
return c == '\n';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsZero(char c)
|
||||
public static bool IsZero(this char c)
|
||||
{
|
||||
return c == '\0';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsSpace(char c)
|
||||
public static bool IsSpace(this char c)
|
||||
{
|
||||
// 2.1 Characters and lines
|
||||
// A space is U+0020.
|
||||
@@ -52,7 +52,7 @@ namespace Textamina.Markdig.Parsing
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsTab(char c)
|
||||
public static bool IsTab(this char c)
|
||||
{
|
||||
// 2.1 Characters and lines
|
||||
// A space is U+0009.
|
||||
@@ -60,13 +60,13 @@ namespace Textamina.Markdig.Parsing
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsSpaceOrTab(char c)
|
||||
public static bool IsSpaceOrTab(this char c)
|
||||
{
|
||||
return IsSpace(c) || IsTab(c);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static char EscapeInsecure(char c)
|
||||
public static char EscapeInsecure(this char c)
|
||||
{
|
||||
// 2.3 Insecure characters
|
||||
// For security reasons, the Unicode character U+0000 must be replaced with the REPLACEMENT CHARACTER (U+FFFD).
|
||||
@@ -74,24 +74,24 @@ namespace Textamina.Markdig.Parsing
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsBulletListMarker(char c)
|
||||
public static bool IsBulletListMarker(this char c)
|
||||
{
|
||||
return c == '-' || c == '+' || c == '*';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsAlphaUpper(char c)
|
||||
public static bool IsAlphaUpper(this char c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public static bool IsAlphaNumeric(char c)
|
||||
public static bool IsAlphaNumeric(this char c)
|
||||
{
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
public static bool IsASCIIPunctuation(char c)
|
||||
public static bool IsAsciiPunctuation(this char c)
|
||||
{
|
||||
// 2.1 Characters and lines
|
||||
// An ASCII punctuation character is !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~.
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Textamina.Markdig.Formatters
|
||||
namespace Textamina.Markdig.Helpers
|
||||
{
|
||||
internal static class EntityDecoder
|
||||
public static class EntityHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Decodes the given HTML entity to the matching Unicode characters.
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Textamina.Markdig.Parsing;
|
||||
using Textamina.Markdig.Formatters;
|
||||
|
||||
namespace Textamina.Markdig.Formatters
|
||||
namespace Textamina.Markdig.Helpers
|
||||
{
|
||||
internal static class HtmlHelper
|
||||
{
|
||||
@@ -31,8 +31,29 @@ namespace Textamina.Markdig.Formatters
|
||||
true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false
|
||||
};
|
||||
|
||||
[ThreadStatic]
|
||||
private static readonly StringBuilder TempBuilder = new StringBuilder();
|
||||
/// <summary>
|
||||
/// List of valid schemes of an URL. The array must be sorted.
|
||||
/// </summary>
|
||||
private static readonly string[] SchemeArray = new[]
|
||||
{
|
||||
"AAA", "AAAS", "ABOUT", "ACAP", "ADIUMXTRA", "AFP", "AFS", "AIM", "APT", "ATTACHMENT", "AW", "BESHARE",
|
||||
"BITCOIN", "BOLO", "CALLTO", "CAP", "CHROME", "CHROME-EXTENSION", "CID", "COAP", "COM-EVENTBRITE-ATTENDEE",
|
||||
"CONTENT", "CRID", "CVS", "DATA", "DAV", "DICT", "DLNA-PLAYCONTAINER", "DLNA-PLAYSINGLE", "DNS", "DOI",
|
||||
"DTN", "DVB", "ED2K", "FACETIME", "FEED", "FILE", "FINGER", "FISH", "FTP", "GEO", "GG", "GIT",
|
||||
"GIZMOPROJECT", "GO", "GOPHER", "GTALK", "H323", "HCP", "HTTP", "HTTPS", "IAX", "ICAP", "ICON", "IM", "IMAP",
|
||||
"INFO", "IPN", "IPP", "IRC", "IRC6", "IRCS", "IRIS", "IRIS.BEEP", "IRIS.LWZ", "IRIS.XPC", "IRIS.XPCS",
|
||||
"ITMS", "JAR", "JAVASCRIPT", "JMS", "KEYPARC", "LASTFM", "LDAP", "LDAPS", "MAGNET", "MAILTO", "MAPS",
|
||||
"MARKET", "MESSAGE", "MID", "MMS", "MS-HELP", "MSNIM", "MSRP", "MSRPS", "MTQP", "MUMBLE", "MUPDATE", "MVN",
|
||||
"NEWS", "NFS", "NI", "NIH", "NNTP", "NOTES", "OID", "OPAQUELOCKTOKEN", "PALM", "PAPARAZZI", "PLATFORM",
|
||||
"POP", "PRES", "PROXY", "PSYC", "QUERY", "RES", "RESOURCE", "RMI", "RSYNC", "RTMP", "RTSP", "SECONDLIFE",
|
||||
"SERVICE", "SESSION", "SFTP", "SGN", "SHTTP", "SIEVE", "SIP", "SIPS", "SKYPE", "SMB", "SMS", "SNMP",
|
||||
"SOAP.BEEP", "SOAP.BEEPS", "SOLDAT", "SPOTIFY", "SSH", "STEAM", "SVN", "TAG", "TEAMSPEAK", "TEL", "TELNET",
|
||||
"TFTP", "THINGS", "THISMESSAGE", "TIP", "TN3270", "TV", "UDP", "UNREAL", "URN", "UT2004", "VEMMI",
|
||||
"VENTRILO", "VIEW-SOURCE", "WEBCAL", "WS", "WSS", "WTAI", "WYCIWYG", "XCON", "XCON-USERID", "XFIRE",
|
||||
"XMLRPC.BEEP", "XMLRPC.BEEPS", "XMPP", "XRI", "YMSGR", "Z39.50R", "Z39.50S"
|
||||
};
|
||||
|
||||
[ThreadStatic] private static readonly StringBuilder TempBuilder = new StringBuilder();
|
||||
|
||||
/// <summary>
|
||||
/// Destructively unescape a string: remove backslashes before punctuation or symbol characters.
|
||||
@@ -45,7 +66,7 @@ namespace Textamina.Markdig.Formatters
|
||||
int lastPos = 0;
|
||||
int match;
|
||||
char c;
|
||||
char[] search = new[] { '\\', '&' };
|
||||
char[] search = new[] {'\\', '&'};
|
||||
var sb = TempBuilder;
|
||||
sb.Clear();
|
||||
|
||||
@@ -60,7 +81,7 @@ namespace Textamina.Markdig.Formatters
|
||||
break;
|
||||
|
||||
c = url[searchPos];
|
||||
if (Utility.IsEscapableSymbol(c))
|
||||
if (CharHelper.IsEscapableSymbol(c))
|
||||
{
|
||||
sb.Append(url, lastPos, searchPos - lastPos - 1);
|
||||
lastPos = searchPos;
|
||||
@@ -70,7 +91,8 @@ namespace Textamina.Markdig.Formatters
|
||||
{
|
||||
string namedEntity;
|
||||
int numericEntity;
|
||||
match = Scanner.scan_entity(url, searchPos, url.Length - searchPos, out namedEntity, out numericEntity);
|
||||
match = scan_entity(url, searchPos, url.Length - searchPos, out namedEntity,
|
||||
out numericEntity);
|
||||
if (match == 0)
|
||||
{
|
||||
searchPos++;
|
||||
@@ -81,7 +103,7 @@ namespace Textamina.Markdig.Formatters
|
||||
|
||||
if (namedEntity != null)
|
||||
{
|
||||
var decoded = EntityDecoder.DecodeEntity(namedEntity);
|
||||
var decoded = EntityHelper.DecodeEntity(namedEntity);
|
||||
if (decoded != null)
|
||||
{
|
||||
sb.Append(url, lastPos, searchPos - match - lastPos);
|
||||
@@ -91,7 +113,7 @@ namespace Textamina.Markdig.Formatters
|
||||
}
|
||||
else if (numericEntity > 0)
|
||||
{
|
||||
var decoded = EntityDecoder.DecodeEntity(numericEntity);
|
||||
var decoded = EntityHelper.DecodeEntity(numericEntity);
|
||||
if (decoded != null)
|
||||
{
|
||||
sb.Append(url, lastPos, searchPos - match - lastPos);
|
||||
@@ -122,7 +144,7 @@ namespace Textamina.Markdig.Formatters
|
||||
/// Escapes special URL characters.
|
||||
/// </summary>
|
||||
/// <remarks>Orig: escape_html(inp, preserve_entities)</remarks>
|
||||
internal static void EscapeUrl(string input, HtmlTextWriter target)
|
||||
public static void EscapeUrl(string input, HtmlTextWriter target)
|
||||
{
|
||||
if (input == null)
|
||||
return;
|
||||
@@ -188,7 +210,7 @@ namespace Textamina.Markdig.Formatters
|
||||
/// Escapes special HTML characters.
|
||||
/// </summary>
|
||||
/// <remarks>Orig: escape_html(inp, preserve_entities)</remarks>
|
||||
internal static void EscapeHtml(string input, HtmlTextWriter target)
|
||||
public static void EscapeHtml(string input, HtmlTextWriter target)
|
||||
{
|
||||
if (input.Length == 0)
|
||||
return;
|
||||
@@ -230,6 +252,7 @@ namespace Textamina.Markdig.Formatters
|
||||
|
||||
target.Write(buffer, lastPos, input.Length - lastPos);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/// <summary>
|
||||
@@ -282,5 +305,121 @@ namespace Textamina.Markdig.Formatters
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Scans an entity.
|
||||
/// Returns number of chars matched.
|
||||
/// </summary>
|
||||
public static int scan_entity(string s, int pos, int length, out string namedEntity, out int numericEntity)
|
||||
{
|
||||
/*!re2c
|
||||
[&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
|
||||
{ return (p - start); }
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
var lastPos = pos + length;
|
||||
|
||||
namedEntity = null;
|
||||
numericEntity = 0;
|
||||
|
||||
if (pos + 3 >= lastPos)
|
||||
return 0;
|
||||
|
||||
if (s[pos] != '&')
|
||||
return 0;
|
||||
|
||||
char c;
|
||||
int i;
|
||||
int counter = 0;
|
||||
if (s[pos + 1] == '#')
|
||||
{
|
||||
c = s[pos + 2];
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
// expect 1-8 hex digits starting from pos+3
|
||||
for (i = pos + 3; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - '0');
|
||||
continue;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - 'A' + 10);
|
||||
continue;
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*16 + (c - 'a' + 10);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// expect 1-8 digits starting from pos+2
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
numericEntity = numericEntity*10 + (c - '0');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// expect a letter and 1-31 letters or digits
|
||||
c = s[pos + 1];
|
||||
if ((c < 'A' || c > 'Z') && (c < 'a' && c > 'z'))
|
||||
return 0;
|
||||
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
{
|
||||
c = s[i];
|
||||
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
||||
{
|
||||
if (++counter == 32)
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
{
|
||||
namedEntity = s.Substring(pos + 1, counter + 1);
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool IsUrlScheme(string scheme)
|
||||
{
|
||||
return Array.BinarySearch(SchemeArray, scheme, StringComparer.Ordinal) >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Syntax;
|
||||
|
||||
namespace Textamina.Markdig.Parsing
|
||||
@@ -381,7 +382,7 @@ namespace Textamina.Markdig.Parsing
|
||||
var c = (char) nextChar;
|
||||
|
||||
// 2.3 Insecure characters
|
||||
c = Utility.EscapeInsecure(c);
|
||||
c = CharHelper.EscapeInsecure(c);
|
||||
|
||||
// Go to next char, expecting most likely a \n, otherwise skip it
|
||||
// TODO: Should we treat it as an error in no \n is following?
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Textamina.Markdig.Parsing;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
@@ -38,7 +39,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else if (!Utility.IsSpace(c) || count == 0)
|
||||
else if (!CharHelper.IsSpace(c) || count == 0)
|
||||
{
|
||||
return MatchLineResult.None;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -33,8 +34,8 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
// 4.4 Indented code blocks
|
||||
var c = liner.Current;
|
||||
var isTab = Utility.IsTab(c);
|
||||
var isSpace = Utility.IsSpace(c);
|
||||
var isTab = CharHelper.IsTab(c);
|
||||
var isSpace = CharHelper.IsSpace(c);
|
||||
if ((isTab || (isSpace && (liner.Start - position) == 3)) && !liner.IsBlankLine())
|
||||
{
|
||||
liner.NextChar();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Textamina.Markdig.Parsing;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
@@ -44,7 +45,7 @@ namespace Textamina.Markdig.Syntax
|
||||
// closing # will be handled later, because anyway we have matched
|
||||
|
||||
// A space is required after leading #
|
||||
if (leadingCount > 0 && leadingCount <=6 && (Utility.IsSpace(c) || liner.IsEol))
|
||||
if (leadingCount > 0 && leadingCount <=6 && (CharHelper.IsSpace(c) || liner.IsEol))
|
||||
{
|
||||
liner.NextChar();
|
||||
state.Block = new HeadingBlock() {Level = leadingCount};
|
||||
@@ -58,7 +59,7 @@ namespace Textamina.Markdig.Syntax
|
||||
c = liner[i];
|
||||
if (endState == 0)
|
||||
{
|
||||
if (Utility.IsSpace(c)) // TODO: Not clear if it is a space or space+tab in the specs
|
||||
if (CharHelper.IsSpace(c)) // TODO: Not clear if it is a space or space+tab in the specs
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
if (countClosingTags > 0)
|
||||
{
|
||||
if (Utility.IsSpace(c))
|
||||
if (CharHelper.IsSpace(c))
|
||||
{
|
||||
liner.End = i - 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -107,7 +108,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (!Utility.IsSpace(liner.PeekChar(index)))
|
||||
if (!CharHelper.IsSpace(liner.PeekChar(index)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +130,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
return CreateHtmlBlock(ref state, HtmlBlockType.Comment); // group 2
|
||||
}
|
||||
if (Utility.IsAlphaUpper(c))
|
||||
if (CharHelper.IsAlphaUpper(c))
|
||||
{
|
||||
return CreateHtmlBlock(ref state, HtmlBlockType.DocumentType); // group 4
|
||||
}
|
||||
@@ -157,14 +158,14 @@ namespace Textamina.Markdig.Syntax
|
||||
for (; count < tag.Length; index++, count++)
|
||||
{
|
||||
c = liner.PeekChar(index);
|
||||
if (!Utility.IsAlphaNumeric(c))
|
||||
if (!CharHelper.IsAlphaNumeric(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
tag[count] = char.ToLowerInvariant(c);
|
||||
}
|
||||
|
||||
if (!(c == '>' || (!hasLeadingClose && c == '/' && liner.PeekChar(index + 1) == '>') || Utility.IsWhitespace(c) || c == '\0'))
|
||||
if (!(c == '>' || (!hasLeadingClose && c == '/' && liner.PeekChar(index + 1) == '>') || CharHelper.IsWhitespace(c) || c == '\0'))
|
||||
{
|
||||
return MatchLineResult.None;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -33,8 +34,8 @@ namespace Textamina.Markdig.Syntax
|
||||
while (c != '\0')
|
||||
{
|
||||
// Skip new lines
|
||||
var isWhitespace = Utility.IsWhitespace(c);
|
||||
if (!(Utility.IsNewLine(c) || (builder.Length == 0 && isWhitespace) || (lastWhiteSpace && isWhitespace)))
|
||||
var isWhitespace = CharHelper.IsWhitespace(c);
|
||||
if (!(CharHelper.IsNewLine(c) || (builder.Length == 0 && isWhitespace) || (lastWhiteSpace && isWhitespace)))
|
||||
{
|
||||
if (c == '`')
|
||||
{
|
||||
@@ -62,7 +63,7 @@ namespace Textamina.Markdig.Syntax
|
||||
int newLength = builder.Length;
|
||||
for (int i = builder.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (Utility.IsWhitespace(builder[i]))
|
||||
if (CharHelper.IsWhitespace(builder[i]))
|
||||
{
|
||||
newLength--;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -41,11 +42,11 @@ namespace Textamina.Markdig.Syntax
|
||||
// (b) either not followed by a punctuation character, or preceded by Unicode whitespace
|
||||
// or a punctuation character.
|
||||
// For purposes of this definition, the beginning and the end of the line count as Unicode whitespace.
|
||||
var afterIsPunctuation = Utility.IsASCIIPunctuation(c);
|
||||
bool canOpen = !Utility.IsWhiteSpaceOrZero(c) &&
|
||||
var afterIsPunctuation = CharHelper.IsAsciiPunctuation(c);
|
||||
bool canOpen = !CharHelper.IsWhiteSpaceOrZero(c) &&
|
||||
(!afterIsPunctuation ||
|
||||
!Utility.IsWhiteSpaceOrZero(pc) ||
|
||||
!Utility.IsASCIIPunctuation(pc));
|
||||
!CharHelper.IsWhiteSpaceOrZero(pc) ||
|
||||
!CharHelper.IsAsciiPunctuation(pc));
|
||||
|
||||
|
||||
// A right-flanking delimiter run is a delimiter run that is
|
||||
@@ -53,11 +54,11 @@ namespace Textamina.Markdig.Syntax
|
||||
// (b) either not preceded by a punctuation character, or followed by Unicode whitespace
|
||||
// or a punctuation character.
|
||||
// For purposes of this definition, the beginning and the end of the line count as Unicode whitespace.
|
||||
var beforeIsPunctuation = Utility.IsASCIIPunctuation(pc);
|
||||
bool canClose = !Utility.IsWhiteSpaceOrZero(pc) &&
|
||||
var beforeIsPunctuation = CharHelper.IsAsciiPunctuation(pc);
|
||||
bool canClose = !CharHelper.IsWhiteSpaceOrZero(pc) &&
|
||||
(!beforeIsPunctuation ||
|
||||
!Utility.IsWhiteSpaceOrZero(c) ||
|
||||
!Utility.IsASCIIPunctuation(c));
|
||||
!CharHelper.IsWhiteSpaceOrZero(c) ||
|
||||
!CharHelper.IsAsciiPunctuation(c));
|
||||
|
||||
if (delimiterChar == '_')
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -21,7 +22,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
// Go to escape character
|
||||
lines.NextChar();
|
||||
if (Utility.IsASCIIPunctuation(lines.Current))
|
||||
if (CharHelper.IsAsciiPunctuation(lines.Current))
|
||||
{
|
||||
state.Inline = new EscapeInline() {EscapedChar = lines.Current};
|
||||
lines.NextChar();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Textamina.Markdig.Formatters;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -113,7 +114,7 @@ namespace Textamina.Markdig.Syntax
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasEscape && !Utility.IsASCIIPunctuation(c))
|
||||
if (hasEscape && !CharHelper.IsAsciiPunctuation(c))
|
||||
{
|
||||
buffer.Append('\\');
|
||||
}
|
||||
@@ -173,7 +174,7 @@ namespace Textamina.Markdig.Syntax
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasEscape && !Utility.IsASCIIPunctuation(c))
|
||||
if (hasEscape && !CharHelper.IsAsciiPunctuation(c))
|
||||
{
|
||||
buffer.Append('\\');
|
||||
}
|
||||
@@ -186,7 +187,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
hasEscape = false;
|
||||
|
||||
if (Utility.IsWhitespace(c)) // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
if (CharHelper.IsWhitespace(c)) // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -231,7 +232,7 @@ namespace Textamina.Markdig.Syntax
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEscape && !Utility.IsASCIIPunctuation(c))
|
||||
if (hasEscape && !CharHelper.IsAsciiPunctuation(c))
|
||||
{
|
||||
buffer.Append('\\');
|
||||
}
|
||||
@@ -246,7 +247,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
hasEscape = false;
|
||||
|
||||
if (Utility.IsSpaceOrTab(c) || Utility.IsControl(c)) // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
if (CharHelper.IsSpaceOrTab(c) || CharHelper.IsControl(c)) // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
{
|
||||
isValid = true;
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
|
||||
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -48,7 +50,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
var c = liner.Current;
|
||||
var startPosition = liner.Column;
|
||||
while (Utility.IsSpaceOrTab(c))
|
||||
while (CharHelper.IsSpaceOrTab(c))
|
||||
{
|
||||
c = liner.NextChar();
|
||||
var endPosition = liner.Column;
|
||||
@@ -71,7 +73,7 @@ namespace Textamina.Markdig.Syntax
|
||||
liner.SkipLeadingSpaces3();
|
||||
var preIndent = liner.Start - preStartPosition;
|
||||
var c = liner.Current;
|
||||
if (Utility.IsBulletListMarker(c))
|
||||
if (CharHelper.IsBulletListMarker(c))
|
||||
{
|
||||
var listType = c;
|
||||
|
||||
@@ -82,7 +84,7 @@ namespace Textamina.Markdig.Syntax
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
c = liner.NextChar();
|
||||
if (!Utility.IsSpaceOrTab(c))
|
||||
if (!CharHelper.IsSpaceOrTab(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
|
||||
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -55,7 +56,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
if (checkForSpaces)
|
||||
{
|
||||
if (!Utility.IsSpaceOrTab(c))
|
||||
if (!CharHelper.IsSpaceOrTab(c))
|
||||
{
|
||||
headingChar = (char)0;
|
||||
break;
|
||||
@@ -63,7 +64,7 @@ namespace Textamina.Markdig.Syntax
|
||||
}
|
||||
else if (c != headingChar)
|
||||
{
|
||||
if (Utility.IsSpaceOrTab(c))
|
||||
if (CharHelper.IsSpaceOrTab(c))
|
||||
{
|
||||
checkForSpaces = true;
|
||||
}
|
||||
@@ -93,7 +94,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
// Remove leading spaces from paragraph
|
||||
var c = liner.Current;
|
||||
while (Utility.IsSpaceOrTab(c))
|
||||
while (CharHelper.IsSpaceOrTab(c))
|
||||
{
|
||||
c = liner.NextChar();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Textamina.Markdig.Parsing;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace Textamina.Markdig.Syntax
|
||||
}
|
||||
|
||||
c = liner.NextChar();
|
||||
if (Utility.IsSpace(c))
|
||||
if (CharHelper.IsSpace(c))
|
||||
{
|
||||
liner.NextChar();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -63,7 +64,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
// If previous character was a tab make the Column += 4
|
||||
Column++;
|
||||
if (Utility.IsTab(Current))
|
||||
if (CharHelper.IsTab(Current))
|
||||
{
|
||||
// Align the tab on a column
|
||||
Column = ((Column + 3) / 4) * 4;
|
||||
@@ -156,7 +157,7 @@ namespace Textamina.Markdig.Syntax
|
||||
|
||||
for (int i = Start; i <= End; i++)
|
||||
{
|
||||
if (!Utility.IsSpace(Text[i]))
|
||||
if (!CharHelper.IsSpace(Text[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -169,7 +170,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (!Utility.IsSpace(Current))
|
||||
if (!CharHelper.IsSpace(Current))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -186,7 +187,7 @@ namespace Textamina.Markdig.Syntax
|
||||
{
|
||||
// Strip leading spaces
|
||||
var c = Current;
|
||||
while (Utility.IsSpace(c))
|
||||
while (CharHelper.IsSpace(c))
|
||||
{
|
||||
c = NextChar();
|
||||
}
|
||||
@@ -197,7 +198,7 @@ namespace Textamina.Markdig.Syntax
|
||||
for (int i = End; i >= Start; i--)
|
||||
{
|
||||
End = i;
|
||||
if (!Utility.IsSpace(this[i]))
|
||||
if (!CharHelper.IsSpace(this[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using Textamina.Markdig.Helpers;
|
||||
using Textamina.Markdig.Parsing;
|
||||
|
||||
namespace Textamina.Markdig.Syntax
|
||||
@@ -124,7 +125,7 @@ namespace Textamina.Markdig.Syntax
|
||||
public bool SkipWhiteSpaces()
|
||||
{
|
||||
bool hasWhitespaces = false;
|
||||
while (Utility.IsWhitespace(Current))
|
||||
while (CharHelper.IsWhitespace(Current))
|
||||
{
|
||||
NextChar();
|
||||
hasWhitespaces = true;
|
||||
|
||||
@@ -35,11 +35,10 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Formatters\EntityDecoder.cs" />
|
||||
<Compile Include="Helpers\EntityHelper.cs" />
|
||||
<Compile Include="Formatters\HtmlFormatter.cs" />
|
||||
<Compile Include="Formatters\HtmlHelper.cs" />
|
||||
<Compile Include="Helpers\HtmlHelper.cs" />
|
||||
<Compile Include="Formatters\HtmlTextWriter.cs" />
|
||||
<Compile Include="Formatters\Scanner.cs" />
|
||||
<Compile Include="Parsing\InlineParser.cs" />
|
||||
<Compile Include="Parsing\MatchInlineState.cs" />
|
||||
<Compile Include="Parsing\MatchLineState.cs" />
|
||||
@@ -74,7 +73,7 @@
|
||||
<Compile Include="Syntax\ListItemBlock.cs" />
|
||||
<Compile Include="Syntax\QuoteBlock.cs" />
|
||||
<Compile Include="Syntax\BreakBlock.cs" />
|
||||
<Compile Include="Utility.cs" />
|
||||
<Compile Include="Helpers\CharHelper.cs" />
|
||||
<Compile Include="Syntax\CodeBlock.cs" />
|
||||
<Compile Include="Syntax\Document.cs" />
|
||||
<Compile Include="Syntax\FencedCodeBlock.cs" />
|
||||
|
||||
Reference in New Issue
Block a user