diff --git a/.hgsub b/.hgsub
index d3f5a12fa..3bb7e7f36 100644
--- a/.hgsub
+++ b/.hgsub
@@ -1 +1,5 @@
+src/Orchard.Web/Modules/Orchard.Forms = https://hg01.codeplex.com/orchardforms
+src/Orchard.Web/Modules/Orchard.Rules = https://hg01.codeplex.com/orchardrules
+src/Orchard.Web/Modules/Orchard.Tokens = https://hg01.codeplex.com/orchardtokens
+src/Orchard.Web/Modules/Orchard.TaskLease = https://hg01.codeplex.com/orchardtasklease
\ No newline at end of file
diff --git a/.hgsubstate b/.hgsubstate
index e69de29bb..338f554f5 100644
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -0,0 +1,4 @@
+d9555c4ed3edaea5f4bd8cb90685ea1c663a9e1c src/Orchard.Web/Modules/Orchard.Forms
+7eeb2b10fe65f82f69096ac1cb5cbfa9d861e542 src/Orchard.Web/Modules/Orchard.Rules
+7c6d6b4f2d695dd8ec23d6f3062334303082a78a src/Orchard.Web/Modules/Orchard.TaskLease
+3d8ff35c6f8cd1b86b084cb689d8a1f48e2f77c1 src/Orchard.Web/Modules/Orchard.Tokens
diff --git a/AzurePackage.proj b/AzurePackage.proj
index ecb02feb0..b2d984895 100644
--- a/AzurePackage.proj
+++ b/AzurePackage.proj
@@ -14,17 +14,19 @@
$(ServiceFolder)\roles\Orchard.Azure.Web\approot$(CompileFolder)\_PublishedWebsites$(BuildFolder)\Stage
+ $(SrcFolder)\Orchard.Azure\Orchard.Azure.Web\obj\Release\Package\PackageTmp
+
-
-
+
+
-
+
@@ -47,19 +49,23 @@
+
+
+
-
+ Properties="Configuration=Release;DeployOnBuild=true;DeployTarget=Package;PlatformTarget=x64"
+ />
+
+ Properties="Configuration=Release;OutputPath=$(MsDeployFolder)\bin;PlatformTarget=x64"
+ />
@@ -72,7 +78,7 @@
-
+
@@ -80,39 +86,54 @@
+
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
@@ -133,14 +154,14 @@
-
-
+
+
diff --git a/Orchard.proj b/Orchard.proj
index f07bc8a5b..396137df6 100644
--- a/Orchard.proj
+++ b/Orchard.proj
@@ -47,8 +47,8 @@
+
-
@@ -378,6 +378,10 @@
+
+
+
+
diff --git a/lib/claysharp/ClaySharp.dll b/lib/claysharp/ClaySharp.dll
index a5e194cef..51179ddad 100644
Binary files a/lib/claysharp/ClaySharp.dll and b/lib/claysharp/ClaySharp.dll differ
diff --git a/lib/claysharp/ClaySharp.pdb b/lib/claysharp/ClaySharp.pdb
new file mode 100644
index 000000000..991b7fc80
Binary files /dev/null and b/lib/claysharp/ClaySharp.pdb differ
diff --git a/lib/markdown/MarkdownSharp.dll b/lib/markdown/MarkdownSharp.dll
new file mode 100644
index 000000000..b779a466b
Binary files /dev/null and b/lib/markdown/MarkdownSharp.dll differ
diff --git a/lib/markdown/MarkdownSharp.pdb b/lib/markdown/MarkdownSharp.pdb
new file mode 100644
index 000000000..a6695c63c
Binary files /dev/null and b/lib/markdown/MarkdownSharp.pdb differ
diff --git a/lib/markdown/MarkdownSharp.xml b/lib/markdown/MarkdownSharp.xml
new file mode 100644
index 000000000..e76600659
--- /dev/null
+++ b/lib/markdown/MarkdownSharp.xml
@@ -0,0 +1,433 @@
+
+
+
+ MarkdownSharp
+
+
+
+
+ when true, (most) bare plain URLs are auto-hyperlinked
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when true, RETURN becomes a literal newline
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ use ">" for HTML output, or " />" for XHTML output
+
+
+
+
+ when true, problematic URL characters like [, ], (, and so forth will be encoded
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when false, email addresses will never be auto-linked
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when true, bold and italic require non-word characters on either side
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ Markdown is a text-to-HTML conversion tool for web writers.
+ Markdown allows you to write using an easy-to-read, easy-to-write plain text format,
+ then convert it to structurally valid XHTML (or HTML).
+
+
+
+
+ maximum nested depth of [] and () supported by the transform; implementation detail
+
+
+
+
+ Tabs are automatically converted to spaces as part of the transform
+ this constant determines how "wide" those tabs become in spaces
+
+
+
+
+ Create a new Markdown instance using default options
+
+
+
+
+ Create a new Markdown instance and optionally load options from the supplied options parameter.
+
+
+
+
+ Create a new Markdown instance and optionally load options from a configuration
+ file. There they should be stored in the appSettings section, available options are:
+
+ Markdown.StrictBoldItalic (true/false)
+ Markdown.EmptyElementSuffix (">" or " />" without the quotes)
+ Markdown.LinkEmails (true/false)
+ Markdown.AutoNewLines (true/false)
+ Markdown.AutoHyperlink (true/false)
+ Markdown.EncodeProblemUrlCharacters (true/false)
+
+
+
+
+ In the static constuctor we'll initialize what stays the same across all transforms.
+
+
+
+
+ Transforms the provided Markdown-formatted text to HTML;
+ see http://en.wikipedia.org/wiki/Markdown
+
+
+ The order in which other subs are called here is
+ essential. Link and image substitutions need to happen before
+ EscapeSpecialChars(), so that any *'s or _'s in the a
+ and img tags get encoded.
+
+
+
+
+ Perform transformations that form block-level tags like paragraphs, headers, and list items.
+
+
+
+
+ Perform transformations that occur *within* block-level tags like paragraphs, headers, and list items.
+
+
+
+
+ splits on two or more newlines, to form "paragraphs";
+ each paragraph is then unhashed (if it is a hash) or wrapped in HTML p tag
+
+
+
+
+ Reusable pattern to match balanced [brackets]. See Friedl's
+ "Mastering Regular Expressions", 2nd Ed., pp. 328-331.
+
+
+
+
+ Reusable pattern to match balanced (parens). See Friedl's
+ "Mastering Regular Expressions", 2nd Ed., pp. 328-331.
+
+
+
+
+ Strips link definitions from text, stores the URLs and titles in hash references.
+
+
+ ^[id]: url "optional title"
+
+
+
+
+ derived pretty much verbatim from PHP Markdown
+
+
+
+
+ replaces any block-level HTML blocks with hash entries
+
+
+
+
+ returns an array of HTML tokens comprising the input string. Each token is
+ either a tag (possibly with nested, tags contained therein, such
+ as <a href="<MTFoo>">, or a run of text between tags. Each element of the
+ array is a two-element array; the first is either 'tag' or 'text'; the second is
+ the actual value.
+
+
+
+
+ Turn Markdown link shortcuts into HTML anchor tags
+
+
+ [link text](url "title")
+ [link text][id]
+ [id]
+
+
+
+
+ Turn Markdown image shortcuts into HTML img tags.
+
+
+ ![alt text][id]
+ 
+
+
+
+
+ Turn Markdown headers into HTML header tags
+
+
+ Header 1
+ ========
+
+ Header 2
+ --------
+
+ # Header 1
+ ## Header 2
+ ## Header 2 with closing hashes ##
+ ...
+ ###### Header 6
+
+
+
+
+ Turn Markdown horizontal rules into HTML hr tags
+
+
+ ***
+ * * *
+ ---
+ - - -
+
+
+
+
+ Turn Markdown lists into HTML ul and ol and li tags
+
+
+
+
+ Process the contents of a single ordered or unordered list, splitting it
+ into individual list items.
+
+
+
+
+ /// Turn Markdown 4-space indented code into HTML pre code blocks
+
+
+
+
+ Turn Markdown `code spans` into HTML code tags
+
+
+
+
+ Turn Markdown *italics* and **bold** into HTML strong and em tags
+
+
+
+
+ Turn markdown line breaks (two space at end of line) into HTML break tags
+
+
+
+
+ Turn Markdown > quoted blocks into HTML blockquote blocks
+
+
+
+
+ Turn angle-delimited URLs into HTML anchor tags
+
+
+ <http://www.example.com>
+
+
+
+
+ Remove one level of line-leading spaces
+
+
+
+
+ encodes email address randomly
+ roughly 10% raw, 45% hex, 45% dec
+ note that @ is always encoded and : never is
+
+
+
+
+ Encode/escape certain Markdown characters inside code blocks and spans where they are literals
+
+
+
+
+ Encode any ampersands (that aren't part of an HTML entity) and left or right angle brackets
+
+
+
+
+ Encodes any escaped characters such as \`, \*, \[ etc
+
+
+
+
+ swap back in all the special characters we've hidden
+
+
+
+
+ escapes Bold [ * ] and Italic [ _ ] characters
+
+
+
+
+ hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems
+
+
+
+
+ Within tags -- meaning between < and > -- encode [\ ` * _] so they
+ don't conflict with their use in Markdown for code, italics and strong.
+ We're replacing each such character with its corresponding hash
+ value; this is likely overkill, but it should prevent us from colliding
+ with the escape values by accident.
+
+
+
+
+ convert all tabs to _tabWidth spaces;
+ standardizes line endings from DOS (CR LF) or Mac (CR) to UNIX (LF);
+ makes sure text ends with a couple of newlines;
+ removes any blank lines (only spaces) in the text
+
+
+
+
+ this is to emulate what's evailable in PHP
+
+
+
+
+ current version of MarkdownSharp;
+ see http://code.google.com/p/markdownsharp/ for the latest code or to contribute
+
+
+
+
+ Static constructor
+
+
+ In the static constuctor we'll initialize what stays the same across all transforms.
+
+
+
+
+
+ Strips link definitions from text, stores the URLs and titles in hash references.
+
+ Link defs are in the form: ^[id]: url "optional title"
+
+
+
+ Hashify HTML blocks
+
+
+
+
+ These are all the transformations that form block-level
+ tags like paragraphs, headers, and list items.
+
+
+
+
+ These are all the transformations that occur *within* block-level
+ tags like paragraphs, headers, and list items.
+
+
+
+
+
+
+
+ Process the contents of a single ordered or unordered list, splitting it
+ into individual list items.
+
+
+
+
+ Encode/escape certain characters inside Markdown code runs.
+
+
+ The point is that in code, these characters are literals, and lose their
+ special Markdown meanings.
+
+
+
+
+ Smart processing for ampersands and angle brackets that need to be encoded.
+
+
+
+
+ Swap back in all the special characters we've hidden.
+
+
+
+
+ Remove one level of line-leading tabs or spaces
+
+
+
+
+ This is to emulate what's evailable in PHP
+
+
+
+
+
+
+
+ Calculate an MD5 hash of an arbitrary string
+
+
+
+
+
+
+ when true, (most) bare plain URLs are auto-hyperlinked
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when true, RETURN becomes a literal newline
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ use ">" for HTML output, or " />" for XHTML output
+
+
+
+
+ when true, problematic URL characters like [, ], (, and so forth will be encoded
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when false, email addresses will never be auto-linked
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
+ when true, bold and italic require non-word characters on either side
+ WARNING: this is a significant deviation from the markdown spec
+
+
+
+
diff --git a/lib/msdeploy/TBEX.xml b/lib/msdeploy/TBEX.xml
new file mode 100644
index 000000000..3c2fc97b2
--- /dev/null
+++ b/lib/msdeploy/TBEX.xml
@@ -0,0 +1,75 @@
+
+
+
+
+ Getting Started with Orchard
+ Welcome to the Orchard community! We want your experience with your new site to be as smooth as possible. Please read this to get started...
+ http://orchardproject.net/docs/Getting-Started.ashx
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+ Free Pluralsight Training on Orchard
+ Watch Pluralsight's free introduction to Orchard course.
+ http://www.pluralsight-training.net/microsoft/players/PSODPlayer.aspx?author=kevin-kuebler&name=introduction-to-orchard&mode=live&clip=0&course=orchard-fundamentals
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+ More documentation
+ We have documentation available on a variety of topics.
+ http://orchardproject.net/docs/
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+ More videos
+ Learn through these great video tutorials.
+ http://orchardproject.net/docs/Orchard-TV.ashx
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+ Orchard Gallery
+ Hundreds of free modules and themes are available from our gallery.
+ http://orchardproject.net/gallery
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+ Orchard Forums
+ If you have questions, suggestions or just want to hang out with other Orchard users and experts, please visit our forums.
+ http://orchard.codeplex.com/discussions
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+
+
+
+ /admin
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/orchardicon.png
+
+
+
+ /Packaging/Gallery/Modules
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/o.png
+
+
+
+ /Packaging/Gallery/Themes
+ http://orchardproject.net/Themes/OrchardProject.Net/Images/o.png
+
+
+
+
+ modules
+
+
+ themes
+
+
+ media
+
+
+ web.config
+
+
+ *
+
+
+
diff --git a/src/Orchard.Azure/AzureFileSystem.cs b/src/Orchard.Azure/AzureFileSystem.cs
index f1b594959..1697ba9d3 100644
--- a/src/Orchard.Azure/AzureFileSystem.cs
+++ b/src/Orchard.Azure/AzureFileSystem.cs
@@ -345,11 +345,15 @@ namespace Orchard.Azure {
}
public string GetPath() {
- return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/');
+ using (new HttpContextWeaver()) {
+ return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/');
+ }
}
public long GetSize() {
- return GetDirectorySize(_blob);
+ using (new HttpContextWeaver()) {
+ return GetDirectorySize(_blob);
+ }
}
public DateTime GetLastUpdated() {
@@ -357,8 +361,10 @@ namespace Orchard.Azure {
}
public IStorageFolder GetParent() {
- if ( _blob.Parent != null ) {
- return new AzureBlobFolderStorage(_blob.Parent, _rootPath);
+ using (new HttpContextWeaver()) {
+ if (_blob.Parent != null) {
+ return new AzureBlobFolderStorage(_blob.Parent, _rootPath);
+ }
}
throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory");
}
diff --git a/src/Orchard.Azure/Logging/AzureAppender.cs b/src/Orchard.Azure/Logging/AzureAppender.cs
new file mode 100644
index 000000000..e5fc5d261
--- /dev/null
+++ b/src/Orchard.Azure/Logging/AzureAppender.cs
@@ -0,0 +1,40 @@
+using System;
+using Microsoft.WindowsAzure;
+using Microsoft.WindowsAzure.Diagnostics.Management;
+using Microsoft.WindowsAzure.ServiceRuntime;
+using log4net.Appender;
+using log4net.Core;
+
+namespace Orchard.Azure.Logging {
+
+ ///
+ /// Azure specific implementation of a log4net appender.
+ /// Uses DataConnectionString to define the location of the log.
+ ///
+ public class AzureAppender : AppenderSkeleton {
+ private const string WadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
+
+ public AzureAppender() {
+
+ var cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue(WadConnectionString));
+
+ var roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
+ RoleEnvironment.DeploymentId,
+ RoleEnvironment.CurrentRoleInstance.Role.Name,
+ RoleEnvironment.CurrentRoleInstance.Id);
+
+ var diagnosticMonitorConfiguration = roleInstanceDiagnosticManager.GetCurrentConfiguration();
+ diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
+ diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d);
+
+ roleInstanceDiagnosticManager.SetCurrentConfiguration(diagnosticMonitorConfiguration);
+ }
+
+ protected override void Append(LoggingEvent loggingEvent) {
+ var formattedLog = RenderLoggingEvent(loggingEvent);
+
+ // this is the way to logging into Azure
+ System.Diagnostics.Trace.WriteLine(formattedLog);
+ }
+ }
+}
diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/Orchard.Azure.CloudService.ccproj b/src/Orchard.Azure/Orchard.Azure.CloudService/Orchard.Azure.CloudService.ccproj
index 4d2726fc6..84a86b69e 100644
--- a/src/Orchard.Azure/Orchard.Azure.CloudService/Orchard.Azure.CloudService.ccproj
+++ b/src/Orchard.Azure/Orchard.Azure.CloudService/Orchard.Azure.CloudService.ccproj
@@ -1,9 +1,10 @@
+ DebugAnyCPU
- 1.3.0
+ 1.5.0{03c5327d-4e8e-45a7-acd1-e18e7caa3c4a}LibraryProperties
@@ -45,7 +46,8 @@
- $(MSBuildExtensionsPath)\Microsoft\Cloud Service\1.0\Visual Studio 10.0\
+ 10.0
+ $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Windows Azure Tools\1.5\
-
+
\ No newline at end of file
diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg
index 9600d5e76..d4c117dfc 100644
--- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg
+++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceConfiguration.cscfg
@@ -4,6 +4,7 @@
+
\ No newline at end of file
diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
index 3503cc02c..e59d35ce6 100644
--- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
+++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
@@ -8,6 +8,9 @@
+
+
+
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config
index 7b1b9b36c..c41a6b0c8 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Config/log4net.config
@@ -3,26 +3,25 @@
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
index 6781b1839..3a862ed45 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
@@ -85,11 +85,7 @@
False
-
- False
- ..\..\..\lib\sqlce\System.Data.SqlServerCe.dll
- True
-
+ False
diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Web.config b/src/Orchard.Azure/Orchard.Azure.Web/Web.config
index 7c86d8a39..23c55dc82 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Web.config
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Web.config
@@ -36,6 +36,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/Title/Views/EditorTemplates/Parts.Title.TitlePart.cshtml b/src/Orchard.Web/Core/Title/Views/EditorTemplates/Parts.Title.TitlePart.cshtml
new file mode 100644
index 000000000..db41838e7
--- /dev/null
+++ b/src/Orchard.Web/Core/Title/Views/EditorTemplates/Parts.Title.TitlePart.cshtml
@@ -0,0 +1,6 @@
+@model Orchard.Core.Title.Models.TitlePart
+
+
diff --git a/src/Orchard.Web/Core/Title/Views/Parts.Title.cshtml b/src/Orchard.Web/Core/Title/Views/Parts.Title.cshtml
new file mode 100644
index 000000000..6024082e2
--- /dev/null
+++ b/src/Orchard.Web/Core/Title/Views/Parts.Title.cshtml
@@ -0,0 +1 @@
+
@Model.Title
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/Title/Views/Parts.Title_Summary.cshtml b/src/Orchard.Web/Core/Title/Views/Parts.Title_Summary.cshtml
new file mode 100644
index 000000000..a1e1e7ed0
--- /dev/null
+++ b/src/Orchard.Web/Core/Title/Views/Parts.Title_Summary.cshtml
@@ -0,0 +1,6 @@
+@{
+ Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem;
+ string title = Model.Title.ToString();
+}
+
+
@Html.ItemDisplayLink(title, contentItem)
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/Title/Views/Parts.Title_SummaryAdmin.cshtml b/src/Orchard.Web/Core/Title/Views/Parts.Title_SummaryAdmin.cshtml
new file mode 100644
index 000000000..552cf4c0c
--- /dev/null
+++ b/src/Orchard.Web/Core/Title/Views/Parts.Title_SummaryAdmin.cshtml
@@ -0,0 +1,6 @@
+@{
+ Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem;
+ string title = Model.Title.ToString();
+}
+
+
\n\n"; }
+ );
+
+ text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
+ function (matchFound, m1) { return "
" + _RunSpanGamut(m1) + "
\n\n"; }
+ );
+
+ // atx-style headers:
+ // # Header 1
+ // ## Header 2
+ // ## Header 2 with closing hashes ##
+ // ...
+ // ###### Header 6
+ //
+
+ /*
+ text = text.replace(/
+ ^(\#{1,6}) // $1 = string of #'s
+ [ \t]*
+ (.+?) // $2 = Header text
+ [ \t]*
+ \#* // optional closing #'s (not counted)
+ \n+
+ /gm, function() {...});
+ */
+
+ text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
+ function (wholeMatch, m1, m2) {
+ var h_level = m1.length;
+ return "" + _RunSpanGamut(m2) + "\n\n";
+ }
+ );
+
+ return text;
+ }
+
+ function _DoLists(text) {
+ //
+ // Form HTML ordered (numbered) and unordered (bulleted) lists.
+ //
+
+ // attacklab: add sentinel to hack around khtml/safari bug:
+ // http://bugs.webkit.org/show_bug.cgi?id=11231
+ text += "~0";
+
+ // Re-usable pattern to match any entirel ul or ol list:
+
+ /*
+ var whole_list = /
+ ( // $1 = whole list
+ ( // $2
+ [ ]{0,3} // attacklab: g_tab_width - 1
+ ([*+-]|\d+[.]) // $3 = first list item marker
+ [ \t]+
+ )
+ [^\r]+?
+ ( // $4
+ ~0 // sentinel for workaround; should be $
+ |
+ \n{2,}
+ (?=\S)
+ (?! // Negative lookahead for another list item marker
+ [ \t]*
+ (?:[*+-]|\d+[.])[ \t]+
+ )
+ )
+ )
+ /g
+ */
+ var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
+
+ if (g_list_level) {
+ text = text.replace(whole_list, function (wholeMatch, m1, m2) {
+ var list = m1;
+ var list_type = (m2.search(/[*+-]/g) > -1) ? "ul" : "ol";
+
+ var result = _ProcessListItems(list, list_type);
+
+ // Trim any trailing whitespace, to put the closing `$list_type>`
+ // up on the preceding line, to get it past the current stupid
+ // HTML block parser. This is a hack to work around the terrible
+ // hack that is the HTML block parser.
+ result = result.replace(/\s+$/, "");
+ result = "<" + list_type + ">" + result + "" + list_type + ">\n";
+ return result;
+ });
+ } else {
+ whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
+ text = text.replace(whole_list, function (wholeMatch, m1, m2, m3) {
+ var runup = m1;
+ var list = m2;
+
+ var list_type = (m3.search(/[*+-]/g) > -1) ? "ul" : "ol";
+ var result = _ProcessListItems(list, list_type);
+ result = runup + "<" + list_type + ">\n" + result + "" + list_type + ">\n";
+ return result;
+ });
+ }
+
+ // attacklab: strip sentinel
+ text = text.replace(/~0/, "");
+
+ return text;
+ }
+
+ var _listItemMarkers = { ol: "\\d+[.]", ul: "[*+-]" };
+
+ function _ProcessListItems(list_str, list_type) {
+ //
+ // Process the contents of a single ordered or unordered list, splitting it
+ // into individual list items.
+ //
+ // list_type is either "ul" or "ol".
+
+ // The $g_list_level global keeps track of when we're inside a list.
+ // Each time we enter a list, we increment it; when we leave a list,
+ // we decrement. If it's zero, we're not in a list anymore.
+ //
+ // We do this because when we're not inside a list, we want to treat
+ // something like this:
+ //
+ // I recommend upgrading to version
+ // 8. Oops, now this line is treated
+ // as a sub-list.
+ //
+ // As a single paragraph, despite the fact that the second line starts
+ // with a digit-period-space sequence.
+ //
+ // Whereas when we're inside a list (or sub-list), that line will be
+ // treated as the start of a sub-list. What a kludge, huh? This is
+ // an aspect of Markdown's syntax that's hard to parse perfectly
+ // without resorting to mind-reading. Perhaps the solution is to
+ // change the syntax rules such that sub-lists must start with a
+ // starting cardinal number; e.g. "1." or "a.".
+
+ g_list_level++;
+
+ // trim trailing blank lines:
+ list_str = list_str.replace(/\n{2,}$/, "\n");
+
+ // attacklab: add sentinel to emulate \z
+ list_str += "~0";
+
+ // In the original attacklab showdown, list_type was not given to this function, and anything
+ // that matched /[*+-]|\d+[.]/ would just create the next
, causing this mismatch:
+ //
+ // Markdown rendered by WMD rendered by MarkdownSharp
+ // ------------------------------------------------------------------
+ // 1. first 1. first 1. first
+ // 2. second 2. second 2. second
+ // - third 3. third * third
+ //
+ // We changed this to behave identical to MarkdownSharp. This is the constructed RegEx,
+ // with {MARKER} being one of \d+[.] or [*+-], depending on list_type:
+
+ /*
+ list_str = list_str.replace(/
+ (^[ \t]*) // leading whitespace = $1
+ ({MARKER}) [ \t]+ // list marker = $2
+ ([^\r]+? // list item text = $3
+ (\n+)
+ )
+ (?=
+ (~0 | \2 ({MARKER}) [ \t]+)
+ )
+ /gm, function(){...});
+ */
+
+ var marker = _listItemMarkers[list_type];
+ var re = new RegExp("(^[ \\t]*)(" + marker + ")[ \\t]+([^\\r]+?(\\n+))(?=(~0|\\1(" + marker + ")[ \\t]+))", "gm");
+ var last_item_had_a_double_newline = false;
+ list_str = list_str.replace(re,
+ function (wholeMatch, m1, m2, m3) {
+ var item = m3;
+ var leading_space = m1;
+ var ends_with_double_newline = /\n\n$/.test(item);
+ var contains_double_newline = ends_with_double_newline || item.search(/\n{2,}/) > -1;
+
+ if (contains_double_newline || last_item_had_a_double_newline) {
+ item = _RunBlockGamut(_Outdent(item), /* doNotUnhash = */true);
+ }
+ else {
+ // Recursion for sub-lists:
+ item = _DoLists(_Outdent(item));
+ item = item.replace(/\n$/, ""); // chomp(item)
+ item = _RunSpanGamut(item);
+ }
+ last_item_had_a_double_newline = ends_with_double_newline;
+ return "
` blocks.
+ //
+
+ /*
+ text = text.replace(/
+ (?:\n\n|^)
+ ( // $1 = the code block -- one or more lines, starting with a space/tab
+ (?:
+ (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
+ .*\n+
+ )+
+ )
+ (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
+ /g ,function(){...});
+ */
+
+ // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
+ text += "~0";
+
+ text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
+ function (wholeMatch, m1, m2) {
+ var codeblock = m1;
+ var nextChar = m2;
+
+ codeblock = _EncodeCode(_Outdent(codeblock));
+ codeblock = _Detab(codeblock);
+ codeblock = codeblock.replace(/^\n+/g, ""); // trim leading newlines
+ codeblock = codeblock.replace(/\n+$/g, ""); // trim trailing whitespace
+
+ codeblock = "
" + codeblock + "\n
";
+
+ return "\n\n" + codeblock + "\n\n" + nextChar;
+ }
+ );
+
+ // attacklab: strip sentinel
+ text = text.replace(/~0/, "");
+
+ return text;
+ }
+
+ function hashBlock(text) {
+ text = text.replace(/(^\n+|\n+$)/g, "");
+ return "\n\n~K" + (g_html_blocks.push(text) - 1) + "K\n\n";
+ }
+
+ function _DoCodeSpans(text) {
+ //
+ // * Backtick quotes are used for spans.
+ //
+ // * You can use multiple backticks as the delimiters if you want to
+ // include literal backticks in the code span. So, this input:
+ //
+ // Just type ``foo `bar` baz`` at the prompt.
+ //
+ // Will translate to:
+ //
+ //
Just type foo `bar` baz at the prompt.
+ //
+ // There's no arbitrary limit to the number of backticks you
+ // can use as delimters. If you need three consecutive backticks
+ // in your code, use four for delimiters, etc.
+ //
+ // * You can use spaces to get literal backticks at the edges:
+ //
+ // ... type `` `bar` `` ...
+ //
+ // Turns to:
+ //
+ // ... type `bar` ...
+ //
+
+ /*
+ text = text.replace(/
+ (^|[^\\]) // Character before opening ` can't be a backslash
+ (`+) // $2 = Opening run of `
+ ( // $3 = The code block
+ [^\r]*?
+ [^`] // attacklab: work around lack of lookbehind
+ )
+ \2 // Matching closer
+ (?!`)
+ /gm, function(){...});
+ */
+
+ text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
+ function (wholeMatch, m1, m2, m3, m4) {
+ var c = m3;
+ c = c.replace(/^([ \t]*)/g, ""); // leading whitespace
+ c = c.replace(/[ \t]*$/g, ""); // trailing whitespace
+ c = _EncodeCode(c);
+ return m1 + "" + c + "";
+ }
+ );
+
+ return text;
+ }
+
+ function _EncodeCode(text) {
+ //
+ // Encode/escape certain characters inside Markdown code runs.
+ // The point is that in code, these characters are literals,
+ // and lose their special Markdown meanings.
+ //
+ // Encode all ampersands; HTML entities are not
+ // entities within a Markdown code span.
+ text = text.replace(/&/g, "&");
+
+ // Do the angle bracket song and dance:
+ text = text.replace(//g, ">");
+
+ // Now, escape characters that are magic in Markdown:
+ text = escapeCharacters(text, "\*_{}[]\\", false);
+
+ // jj the line above breaks this:
+ //---
+
+ //* Item
+
+ // 1. Subitem
+
+ // special char: *
+ //---
+
+ return text;
+ }
+
+ function _DoItalicsAndBold(text) {
+
+ // must go first:
+ text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g,
+ "$1$3$4");
+
+ text = text.replace(/([\W_]|^)(\*|_)(?=\S)([^\r\*_]*?\S)\2([\W_]|$)/g,
+ "$1$3$4");
+
+ return text;
+ }
+
+ function _DoBlockQuotes(text) {
+
+ /*
+ text = text.replace(/
+ ( // Wrap whole match in $1
+ (
+ ^[ \t]*>[ \t]? // '>' at the start of a line
+ .+\n // rest of the first line
+ (.+\n)* // subsequent consecutive lines
+ \n* // blanks
+ )+
+ )
+ /gm, function(){...});
+ */
+
+ text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
+ function (wholeMatch, m1) {
+ var bq = m1;
+
+ // attacklab: hack around Konqueror 3.5.4 bug:
+ // "----------bug".replace(/^-/g,"") == "bug"
+
+ bq = bq.replace(/^[ \t]*>[ \t]?/gm, "~0"); // trim one level of quoting
+
+ // attacklab: clean up hack
+ bq = bq.replace(/~0/g, "");
+
+ bq = bq.replace(/^[ \t]+$/gm, ""); // trim whitespace-only lines
+ bq = _RunBlockGamut(bq); // recurse
+
+ bq = bq.replace(/(^|\n)/g, "$1 ");
+ // These leading spaces screw with
content, so we need to fix that:
+ bq = bq.replace(
+ /(\s*
[^\r]+?<\/pre>)/gm,
+ function (wholeMatch, m1) {
+ var pre = m1;
+ // attacklab: hack around Konqueror 3.5.4 bug:
+ pre = pre.replace(/^ /mg, "~0");
+ pre = pre.replace(/~0/g, "");
+ return pre;
+ });
+
+ return hashBlock("
\n" + bq + "\n
");
+ }
+ );
+ return text;
+ }
+
+ function _FormParagraphs(text, doNotUnhash) {
+ //
+ // Params:
+ // $text - string to process with html
tags
+ //
+
+ // Strip leading and trailing lines:
+ text = text.replace(/^\n+/g, "");
+ text = text.replace(/\n+$/g, "");
+
+ var grafs = text.split(/\n{2,}/g);
+ var grafsOut = [];
+
+ var markerRe = /~K(\d+)K/;
+
+ //
+ // Wrap
tags.
+ //
+ var end = grafs.length;
+ for (var i = 0; i < end; i++) {
+ var str = grafs[i];
+
+ // if this is an HTML marker, copy it
+ if (markerRe.test(str)) {
+ grafsOut.push(str);
+ }
+ else if (/\S/.test(str)) {
+ str = _RunSpanGamut(str);
+ str = str.replace(/^([ \t]*)/g, "
");
+ str += "
"
+ grafsOut.push(str);
+ }
+
+ }
+ //
+ // Unhashify HTML blocks
+ //
+ if (!doNotUnhash) {
+ end = grafsOut.length;
+ for (var i = 0; i < end; i++) {
+ var foundAny = true;
+ while (foundAny) { // we may need several runs, since the data may be nested
+ foundAny = false;
+ grafsOut[i] = grafsOut[i].replace(/~K(\d+)K/g, function (wholeMatch, id) {
+ foundAny = true;
+ return g_html_blocks[id];
+ });
+ }
+ }
+ }
+ return grafsOut.join("\n\n");
+ }
+
+ function _EncodeAmpsAndAngles(text) {
+ // Smart processing for ampersands and angle brackets that need to be encoded.
+
+ // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
+ // http://bumppo.net/projects/amputator/
+ text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&");
+
+ // Encode naked <'s
+ text = text.replace(/<(?![a-z\/?\$!])/gi, "<");
+
+ return text;
+ }
+
+ function _EncodeBackslashEscapes(text) {
+ //
+ // Parameter: String.
+ // Returns: The string, with after processing the following backslash
+ // escape sequences.
+ //
+
+ // attacklab: The polite way to do this is with the new
+ // escapeCharacters() function:
+ //
+ // text = escapeCharacters(text,"\\",true);
+ // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
+ //
+ // ...but we're sidestepping its use of the (slow) RegExp constructor
+ // as an optimization for Firefox. This function gets called a LOT.
+
+ text = text.replace(/\\(\\)/g, escapeCharacters_callback);
+ text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, escapeCharacters_callback);
+ return text;
+ }
+
+ function _DoAutoLinks(text) {
+
+ // note that at this point, all other URL in the text are already hyperlinked as
+ // *except* for the case
+
+ // automatically add < and > around unadorned raw hyperlinks
+ // must be preceded by space/BOF and followed by non-word/EOF character
+ text = text.replace(/(^|\s)(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\]])($|\W)/gi, "$1<$2$3>$4");
+
+ // autolink anything like
+
+ var replacer = function (wholematch, m1) { return "" + pluginHooks.plainLinkText(m1) + ""; }
+ text = text.replace(/<((https?|ftp):[^'">\s]+)>/gi, replacer);
+
+ // Email addresses:
+ /*
+ text = text.replace(/
+ <
+ (?:mailto:)?
+ (
+ [-.\w]+
+ \@
+ [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
+ )
+ >
+ /gi, _DoAutoLinks_callback());
+ */
+
+ /* disabling email autolinking, since we don't do that on the server, either
+ text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
+ function(wholeMatch,m1) {
+ return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
+ }
+ );
+ */
+ return text;
+ }
+
+ function _UnescapeSpecialChars(text) {
+ //
+ // Swap back in all the special characters we've hidden.
+ //
+ text = text.replace(/~E(\d+)E/g,
+ function (wholeMatch, m1) {
+ var charCodeToReplace = parseInt(m1);
+ return String.fromCharCode(charCodeToReplace);
+ }
+ );
+ return text;
+ }
+
+ function _Outdent(text) {
+ //
+ // Remove one level of line-leading tabs or spaces
+ //
+
+ // attacklab: hack around Konqueror 3.5.4 bug:
+ // "----------bug".replace(/^-/g,"") == "bug"
+
+ text = text.replace(/^(\t|[ ]{1,4})/gm, "~0"); // attacklab: g_tab_width
+
+ // attacklab: clean up hack
+ text = text.replace(/~0/g, "")
+
+ return text;
+ }
+
+ function _Detab(text) {
+ if (!/\t/.test(text))
+ return text;
+
+ var spaces = [" ", " ", " ", " "],
+ skew = 0,
+ v;
+
+ return text.replace(/[\n\t]/g, function (match, offset) {
+ if (match === "\n") {
+ skew = offset + 1;
+ return match;
+ }
+ v = (offset - skew) % 4;
+ skew = offset + 1;
+ return spaces[v];
+ });
+ }
+
+ //
+ // attacklab: Utility functions
+ //
+
+ var _problemUrlChars = /(?:["'*()[\]:]|~D)/g;
+
+ // hex-encodes some unusual "problem" chars in URLs to avoid URL detection problems
+ function encodeProblemUrlChars(url) {
+ if (!url)
+ return "";
+
+ var len = url.length;
+
+ return url.replace(_problemUrlChars, function (match, offset) {
+ if (match == "~D") // escape for dollar
+ return "%24";
+ if (match == ":") {
+ if (offset == len - 1 || /[0-9\/]/.test(url.charAt(offset + 1)))
+ return ":"
+ }
+ return "%" + match.charCodeAt(0).toString(16);
+ });
+ }
+
+
+ function escapeCharacters(text, charsToEscape, afterBackslash) {
+ // First we have to escape the escape characters so that
+ // we can build a character class out of them
+ var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g, "\\$1") + "])";
+
+ if (afterBackslash) {
+ regexString = "\\\\" + regexString;
+ }
+
+ var regex = new RegExp(regexString, "g");
+ text = text.replace(regex, escapeCharacters_callback);
+
+ return text;
+ }
+
+
+ function escapeCharacters_callback(wholeMatch, m1) {
+ var charCodeToEscape = m1.charCodeAt(0);
+ return "~E" + charCodeToEscape + "E";
+ }
+
+ }; // end of the Markdown.Converter constructor
+
+})();
diff --git a/src/Orchard.Web/Modules/Markdown/Scripts/Markdown.Editor.js b/src/Orchard.Web/Modules/Markdown/Scripts/Markdown.Editor.js
new file mode 100644
index 000000000..17f43112c
--- /dev/null
+++ b/src/Orchard.Web/Modules/Markdown/Scripts/Markdown.Editor.js
@@ -0,0 +1,2109 @@
+// needs Markdown.Converter.js at the moment
+
+(function () {
+
+ var util = {},
+ position = {},
+ ui = {},
+ doc = window.document,
+ re = window.RegExp,
+ nav = window.navigator,
+ SETTINGS = { lineLength: 72 },
+
+ // Used to work around some browser bugs where we can't use feature testing.
+ uaSniffed = {
+ isIE: /msie/.test(nav.userAgent.toLowerCase()),
+ isIE_5or6: /msie 6/.test(nav.userAgent.toLowerCase()) || /msie 5/.test(nav.userAgent.toLowerCase()),
+ isOpera: /opera/.test(nav.userAgent.toLowerCase())
+ };
+
+
+ // -------------------------------------------------------------------
+ // YOUR CHANGES GO HERE
+ //
+ // I've tried to localize the things you are likely to change to
+ // this area.
+ // -------------------------------------------------------------------
+
+ // The text that appears on the upper part of the dialog box when
+ // entering links.
+ var linkDialogText = "