From dfa5e04288cb15dd4a1a2338bbf1d3b86d4edd95 Mon Sep 17 00:00:00 2001 From: CRxTRDude Date: Mon, 23 Nov 2015 21:23:59 +0800 Subject: [PATCH 1/6] Initial implementation of MarkdownDeep.net over Journaley. - Replaced MarkdownSharp with MarkdownDeep.net. Has better compatibility with some Markdown features that Day One supports - Added a fix for single line breaks that isn't implemented in MarkdownDeep. Note that this needs some optimization. --- Journaley.Core/Journaley.Core.csproj | 2 + Journaley/Forms/MainForm.cs | 79 +++++++++++++++++------- Journaley/Journaley.csproj | 9 ++- Journaley/packages.config | 2 +- VersionExtractor/VersionExtractor.csproj | 4 ++ 5 files changed, 71 insertions(+), 25 deletions(-) diff --git a/Journaley.Core/Journaley.Core.csproj b/Journaley.Core/Journaley.Core.csproj index 9ce425a..89d791e 100644 --- a/Journaley.Core/Journaley.Core.csproj +++ b/Journaley.Core/Journaley.Core.csproj @@ -97,7 +97,9 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + \n{0}\n\n{1}\n\n{2}\n
{3}
", + "\n\n\n
\n{3}\n
\n\n", this.GetWebBrowserTypefaceCSS(), this.GetWebBrowserSizeCSS(), this.CustomCSS ?? string.Empty, - Markdown.Transform(this.SelectedEntry.EntryText)); + Markdown.Transform(initialString)); + string lineBrokenString = this.AddSingleLineBreak(formattedString); - this.webBrowser.DocumentText = this.RemoveLineBreaksWithinLists(formattedString); + this.webBrowser.DocumentText = lineBrokenString; } /// - /// Removes the wrong line breaks within nested ordered/unordered lists. - /// Hack to fix the issue #114. + /// Adds break tags for single line breaks. /// - /// The entry content formatted by MarkdownSharp. - /// correctly formatted string with the wrong line breaks removed. - private string RemoveLineBreaksWithinLists(string formattedString) + /// Formatted HTML string + /// Properly formatted HTML string with br tags for single line breaks + private string AddSingleLineBreak(string formattedString) { System.Text.StringBuilder builder = new System.Text.StringBuilder(); - string pattern = @"^"; + System.Text.StringBuilder paragraphBuilder = new System.Text.StringBuilder(); + + bool isNewLine = false; + + string newLineString; + string strippedOver; + + Regex paragraphBegin = new Regex(@"(

)", RegexOptions.Multiline); + Regex paragraphEnd = new Regex(@"(

)", RegexOptions.Multiline); var lines = formattedString.Split( new string[] { "\r\n", "\n" }, @@ -666,25 +676,52 @@ private string RemoveLineBreaksWithinLists(string formattedString) for (int i = 0; i < lines.Length - 1; ++i) { string line = lines[i]; - string nextLine = lines[i + 1]; - // Remove the "
" tags only if the current line and the next line are starting - // with the opening/closing list tags. By doing this, it can prevent removing - // line breaks that are intentionally added by the user. - if (Regex.IsMatch(line, pattern) && Regex.IsMatch(nextLine, pattern)) + // We first incrementally check if the line begins with

tag. When it does, + // We turn on the paragraphBuilder to append the remaining lines. + + // If the checks hit a line with the

closing, we disable check and proceed + // to parse the text, add
tags and then adding it to the builder variable + // where it is assembled with the rest of the file. + + // Note, this is unoptimized code and will still need work. + if (paragraphBegin.IsMatch(line)) + { + isNewLine = true; + } + else if (paragraphEnd.IsMatch(line)) + { + isNewLine = false; + } + + if (isNewLine) { - while (line.EndsWith("
")) + paragraphBuilder.AppendLine(line); + + if (paragraphEnd.IsMatch(line)) { - line = line.Substring(0, line.LastIndexOf("
")); + builder.AppendLine(line); + paragraphBuilder.Clear(); + isNewLine = false; } } + else + { + paragraphBuilder.AppendLine(line); + + newLineString = paragraphBuilder.ToString(); + newLineString = Regex.Replace(newLineString, @"^([\w\*\>\<\[][^\r\n]*)(?=\r?\n[\w\*\>\<\[].*$)", "$1
", RegexOptions.Multiline); - builder.AppendLine(line); + builder.AppendLine(newLineString); + paragraphBuilder.Clear(); + } } builder.AppendLine(lines.Last()); - return builder.ToString(); + strippedOver = Regex.Replace(builder.ToString(), @"^(\r\s)", string.Empty, RegexOptions.Multiline); + + return strippedOver; } /// diff --git a/Journaley/Journaley.csproj b/Journaley/Journaley.csproj index aeea8da..8eb4da2 100644 --- a/Journaley/Journaley.csproj +++ b/Journaley/Journaley.csproj @@ -81,9 +81,10 @@ False ..\packages\squirrel.windows.0.99.2\lib\Net45\ICSharpCode.SharpZipLib.dll - - ..\packages\MarkdownSharp.1.13.0.0\lib\35\MarkdownSharp.dll - MDS + + ..\packages\MarkdownDeep.NET.1.5\lib\.NetFramework 3.5\MarkdownDeep.dll + True + MDD ..\packages\winapicp.1.1\lib\Microsoft.WindowsAPICodePack.dll @@ -499,10 +500,12 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + "$(SolutionDir)InsertIcons.exe" "$(TargetPath)" "$(ProjectDir)Images\NewEntry.ico" + \n{0}\n\n{1}\n\n{2}\n\n\n\n
\n{3}\n
\n\n", + "{0}\n\n\n\n
\n{4}\n
\n\n", + docType, this.GetWebBrowserTypefaceCSS(), this.GetWebBrowserSizeCSS(), this.CustomCSS ?? string.Empty, - Markdown.Transform(initialString)); - string lineBrokenString = this.AddSingleLineBreak(formattedString); - - this.webBrowser.DocumentText = lineBrokenString; - } - - /// - /// Adds break tags for single line breaks. - /// - /// Formatted HTML string - /// Properly formatted HTML string with br tags for single line breaks - private string AddSingleLineBreak(string formattedString) - { - System.Text.StringBuilder builder = new System.Text.StringBuilder(); - System.Text.StringBuilder paragraphBuilder = new System.Text.StringBuilder(); - - bool isNewLine = false; - - string newLineString; - string strippedOver; - - Regex paragraphBegin = new Regex(@"(

)", RegexOptions.Multiline); - Regex paragraphEnd = new Regex(@"(

)", RegexOptions.Multiline); - - var lines = formattedString.Split( - new string[] { "\r\n", "\n" }, - StringSplitOptions.None); - - for (int i = 0; i < lines.Length - 1; ++i) - { - string line = lines[i]; - - // We first incrementally check if the line begins with

tag. When it does, - // We turn on the paragraphBuilder to append the remaining lines. - - // If the checks hit a line with the

closing, we disable check and proceed - // to parse the text, add
tags and then adding it to the builder variable - // where it is assembled with the rest of the file. - - // Note, this is unoptimized code and will still need work. - if (paragraphBegin.IsMatch(line)) - { - isNewLine = true; - } - else if (paragraphEnd.IsMatch(line)) - { - isNewLine = false; - } - - if (isNewLine) - { - paragraphBuilder.AppendLine(line); - - if (paragraphEnd.IsMatch(line)) - { - builder.AppendLine(line); - paragraphBuilder.Clear(); - isNewLine = false; - } - } - else - { - paragraphBuilder.AppendLine(line); - - newLineString = paragraphBuilder.ToString(); - newLineString = Regex.Replace(newLineString, @"^([\w\*\>\<\[][^\r\n]*)(?=\r?\n[\w\*\>\<\[].*$)", "$1
", RegexOptions.Multiline); - - builder.AppendLine(newLineString); - paragraphBuilder.Clear(); - } - } - - builder.AppendLine(lines.Last()); - - strippedOver = Regex.Replace(builder.ToString(), @"^(\r\s)", string.Empty, RegexOptions.Multiline); + PostMarkdownParser.PostMarkdown(Markdown.Transform(initialString))); - return strippedOver; + this.webBrowser.DocumentText = formattedString; } /// diff --git a/Journaley/Journaley.csproj b/Journaley/Journaley.csproj index 8eb4da2..2d1e6d1 100644 --- a/Journaley/Journaley.csproj +++ b/Journaley/Journaley.csproj @@ -203,6 +203,7 @@ True Resources.resx + diff --git a/Journaley/Utilities/PostMarkdownParser.cs b/Journaley/Utilities/PostMarkdownParser.cs new file mode 100644 index 0000000..73e9388 --- /dev/null +++ b/Journaley/Utilities/PostMarkdownParser.cs @@ -0,0 +1,114 @@ +namespace Journaley.Utilities +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading.Tasks; + + /// + /// Helper class for fixing MarkdownDeep parsed HTML. + /// + public class PostMarkdownParser + { + /// + /// Perform fixes after MarkdownDeep parsing for publishing + /// to Journaley. + /// + /// Formatted HTML string + /// Properly formatted HTML string for publishing. + public static string PostMarkdown(string formattedString) + { + // First convert all code blocks using

into

+            // which is used in almost all implementations of
+            // Markdown, even in the original Markdown specs.
+            formattedString = Regex.Replace(formattedString, @"

", "

", RegexOptions.Multiline);
+            formattedString = Regex.Replace(formattedString, @"

", "
", RegexOptions.Multiline); + + System.Text.StringBuilder builder = new System.Text.StringBuilder(); + System.Text.StringBuilder paragraphBuilder = new System.Text.StringBuilder(); + + var isNewLine = 0; + + string newLineString; + string strippedOverString; + + var lines = formattedString.Split( + new string[] { "\r\n", "\n" }, + StringSplitOptions.None); + + for (int i = 0; i < lines.Length - 1; ++i) + { + string line = lines[i]; + + // We first incrementally check if the line begins with

tag. When it does, + // We turn on the paragraphBuilder to append the remaining lines. + + // If the checks hit a line with the

closing, we disable check and proceed + // to parse the text, add
tags and then adding it to builder + // where it is assembled with the rest of the file. + + // We dump the text to builder if it hits a
 tag.
+                if (line.Contains("

")) + { + isNewLine = 1; + } + else if (line.Contains("

")) + { + isNewLine = 0; + } + else if (line.Contains("
"))
+                {
+                    isNewLine = -1;
+                }
+
+                if (isNewLine == 1)
+                {
+                    paragraphBuilder.AppendLine(line);
+
+                    if (line.Contains("

")) + { + // Single line strikethroughs. + line = Regex.Replace(line, @"(~~)(.*?)(~~)", "$2", RegexOptions.Multiline); + builder.AppendLine(line); + paragraphBuilder.Clear(); + isNewLine = 0; + } + } + else if (isNewLine == 0) + { + paragraphBuilder.AppendLine(line); + + newLineString = paragraphBuilder.ToString(); + + // Multiline strikethrough. + if (Regex.IsMatch(newLineString, @"(~~)(.*?)(~~)")) + { + newLineString = Regex.Replace(newLineString, @"(~~)(.*?)(~~)", "$2", RegexOptions.Multiline); + } + else + { + newLineString = Regex.Replace(newLineString, @"

(~~)", "

", RegexOptions.Multiline); + newLineString = Regex.Replace(newLineString, @"(~~)

", "

", RegexOptions.Multiline); + } + + newLineString = Regex.Replace(newLineString, @"^([\w\*\>\<\[][^\r\n]*)(?=\r?\n[\w\*\>\<\[].*$)", "$1
", RegexOptions.Multiline); + + builder.AppendLine(newLineString); + paragraphBuilder.Clear(); + } + else + { + // For
 tagged text, just skip check and append to builder
+                    builder.AppendLine(line);
+                }
+            }
+
+            builder.AppendLine(lines.Last());
+            strippedOverString = Regex.Replace(builder.ToString(), @"^(\r\s)", string.Empty, RegexOptions.Multiline);
+
+            return strippedOverString;
+        }
+    }
+}

From 5853c587a9dfed57d2e7f08197f5e88cdb8aa4fb Mon Sep 17 00:00:00 2001
From: crxtrdude 
Date: Tue, 24 Nov 2015 16:54:39 +0800
Subject: [PATCH 3/6] Additional MarkdownDeep fixes ...

- Improved PostMarkdown function as suggested by @yyoon.
- Reverted screwed up csproj files due to Nuget Package Recovery.
- Modified docType string to use HTML5 DOCTYPE standard.
- Minor fixes.
---
 Journaley.Core/Journaley.Core.csproj      |  2 -
 Journaley/Forms/MainForm.cs               |  4 +-
 Journaley/Journaley.csproj                |  2 -
 Journaley/Utilities/PostMarkdownParser.cs | 49 ++++++++++-------------
 VersionExtractor/VersionExtractor.csproj  |  4 --
 5 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/Journaley.Core/Journaley.Core.csproj b/Journaley.Core/Journaley.Core.csproj
index 89d791e..9ce425a 100644
--- a/Journaley.Core/Journaley.Core.csproj
+++ b/Journaley.Core/Journaley.Core.csproj
@@ -97,9 +97,7 @@
       This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
     
     
-    
   
-  
   \n{1}\n\n{2}\n\n{3}\n\n\n\n
\n{4}\n
\n\n", + "{0}\n\n\n\n
\n{4}
\n\n", docType, this.GetWebBrowserTypefaceCSS(), this.GetWebBrowserSizeCSS(), diff --git a/Journaley/Journaley.csproj b/Journaley/Journaley.csproj index 2d1e6d1..a62ff28 100644 --- a/Journaley/Journaley.csproj +++ b/Journaley/Journaley.csproj @@ -501,12 +501,10 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - "$(SolutionDir)InsertIcons.exe" "$(TargetPath)" "$(ProjectDir)Images\NewEntry.ico" -