using
System.Text;
using
System.Web;
using
System.Web.UI.HtmlControls;
using
BlogEngine.Core;
using
BlogEngine.Core.Web.Controls;
using
BlogEngine.Core.Web.Extensions;
using
Page=System.Web.UI.Page;
using
System.Collections.Generic;
using
System;
public
class
SyntaxHighlighter
{
#region Private members
private
const
string
ExtensionName =
"SyntaxHighlighter"
;
static
protected
Dictionary<Guid, ExtensionSettings> _blogsOptions =
new
Dictionary<Guid, ExtensionSettings>();
static
protected
Dictionary<Guid, ExtensionSettings> _blogsThemes =
new
Dictionary<Guid, ExtensionSettings>();
#endregion
/// <summary>
/// The sync root.
/// </summary>
private
static
readonly
object
syncRoot =
new
object
();
private
static
ExtensionSettings Options
{
get
{
Guid blogId = Blog.CurrentInstance.Id;
ExtensionSettings options =
null
;
_blogsOptions.TryGetValue(blogId,
out
options);
if
(options ==
null
)
{
lock
(syncRoot)
{
_blogsOptions.TryGetValue(blogId,
out
options);
if
(options ==
null
)
{
options =
new
ExtensionSettings(
"Options"
);
options.IsScalar =
true
;
options.Help = OptionsHelp();
options.AddParameter(
"cdnScriptsPath"
,
"CDN Script Path"
, 250,
false
);
options.AddParameter(
"cdnStylesPath"
,
"CDN Styles Path"
, 250,
false
);
options.AddParameter(
"gutter"
,
"Gutter"
);
options.AddParameter(
"smart-tabs"
,
"Smart tabs"
);
options.AddParameter(
"auto-links"
,
"Auto links"
);
options.AddParameter(
"collapse"
,
"Collapse"
);
options.AddParameter(
"tab-size"
,
"Tab size"
);
options.AddParameter(
"toolbar"
,
"Toolbar"
);
options.AddValue(
"cdnScriptsPath"
,
""
);
options.AddValue(
"cdnStylesPath"
,
""
);
options.AddValue(
"gutter"
,
true
);
options.AddValue(
"smart-tabs"
,
true
);
options.AddValue(
"auto-links"
,
true
);
options.AddValue(
"collapse"
,
false
);
options.AddValue(
"tab-size"
, 4);
options.AddValue(
"toolbar"
,
true
);
_blogsOptions[blogId] = ExtensionManager.InitSettings(ExtensionName, options);
ExtensionSettings themes =
new
ExtensionSettings(
"Themes"
);
themes.IsScalar =
true
;
themes.AddParameter(
"SelectedTheme"
,
"Themes"
, 20,
false
,
false
, ParameterType.ListBox);
themes.AddValue(
"SelectedTheme"
,
new
string
[] {
"Default"
,
"Django"
,
"Eclipse"
,
"Emacs"
,
"FadeToGrey"
,
"MDUltra"
,
"Midnight"
,
"Dark"
},
"Default"
);
_blogsThemes[blogId] = ExtensionManager.InitSettings(ExtensionName, themes);
}
}
}
return
options;
}
}
private
static
ExtensionSettings Themes
{
get
{
ExtensionSettings options = Options;
return
_blogsThemes[Blog.CurrentInstance.Id];
}
}
static
SyntaxHighlighter()
{
Post.Serving += AddSyntaxHighlighter;
InitSettings();
}
private
static
void
AddSyntaxHighlighter(
object
sender, ServingEventArgs e)
{
if
(!ExtensionManager.ExtensionEnabled(
"SyntaxHighlighter"
))
return
;
if
(e.Location == ServingLocation.Feed)
return
;
if
(!e.Body.ToLowerInvariant().Contains(
"<pre class=\"brush:"
))
return
;
HttpContext context = HttpContext.Current;
Page page = (Page)context.CurrentHandler;
if
((context.CurrentHandler
is
Page ==
false
) || (context.Items[ExtensionName] !=
null
))
{
return
;
}
AddCssStyles(page);
AddJavaScripts(page);
AddOptions(page);
context.Items[ExtensionName] = 1;
}
private
static
void
AddCssStyles(Page page)
{
AddStylesheet(
"shCore.css"
, page);
if
(Themes !=
null
)
{
switch
(Themes.GetSingleValue(
"SelectedTheme"
))
{
case
"Django"
:
AddStylesheet(
"shThemeDjango.css"
, page);
break
;
case
"Eclipse"
:
AddStylesheet(
"shThemeEclipse.css"
, page);
break
;
case
"Emacs"
:
AddStylesheet(
"shThemeEmacs.css"
, page);
break
;
case
"FadeToGrey"
:
AddStylesheet(
"shThemeFadeToGrey.css"
, page);
break
;
case
"MDUltra"
:
AddStylesheet(
"shThemeMDUltra.css"
, page);
break
;
case
"Midnight"
:
AddStylesheet(
"shThemeMidnight.css"
, page);
break
;
case
"Dark"
:
AddStylesheet(
"shThemeRDark.css"
, page);
break
;
default
:
AddStylesheet(
"shThemeDefault.css"
, page);
break
;
}
}
}
private
static
void
AddJavaScripts(Page page)
{
if
(BlogSettings.Instance.EnableOptimization)
{
BlogEngine.Core.Web.Scripting.Helpers.AddScript(
page,
string
.Format(
"{0}Scripts/highlighter"
, Utils.ApplicationRelativeWebRoot),
false
,
true
,
true
);
}
else
{
BlogEngine.Core.Web.Scripting.Helpers.AddScript(
page,
string
.Format(
"{0}Scripts/syntaxhighlighter/shCore.js"
, Utils.ApplicationRelativeWebRoot),
false
,
true
,
true
);
BlogEngine.Core.Web.Scripting.Helpers.AddScript(
page,
string
.Format(
"{0}Scripts/syntaxhighlighter/shAutoloader.js"
, Utils.ApplicationRelativeWebRoot),
false
,
true
,
true
);
BlogEngine.Core.Web.Scripting.Helpers.AddScript(
page,
string
.Format(
"{0}Scripts/syntaxhighlighter/shInit.js"
, Utils.ApplicationRelativeWebRoot),
false
,
true
,
true
);
}
}
#region Script/Style adding
private
static
void
AddJavaScript(
string
src, Page page)
{
page.ClientScript.RegisterStartupScript(page.GetType(), src, String.Format(
"<script type=\"text/javascript\" src=\"{0}\"></script>"
, GetUrl(ScriptsFolder(), src)));
}
private
static
void
AddStylesheet(
string
href, Page page)
{
HtmlLink css =
new
HtmlLink();
css.Attributes[
"type"
] =
"text/css"
;
css.Attributes[
"rel"
] =
"stylesheet"
;
css.Attributes[
"href"
] = GetUrl(StylesFolder(), href);
try
{
if
(page !=
null
&& page.Header !=
null
&& page.Header.Controls !=
null
)
page.Header.Controls.Add(css);
}
catch
(NullReferenceException ex)
{
throw
ex;
}
catch
(Exception ex)
{
throw
ex;
}
}
private
static
void
AddOptions(Page page)
{
StringBuilder sb =
new
StringBuilder();
var
executeOn =
@"
if (typeof executeOn === 'undefined') {
window.executeOn = function (condition, func) {
var interval = setInterval(function () {
try {
var result = false;
if (typeof condition === ""function"") {
result = condition();
} else if (typeof condition === ""string"") {
result = eval(condition);
} else {
throw ""argument 'condition' must be a bool function or a bool expression."";
}
if (result === true) {
clearInterval(interval);
func();
}
} catch (ex) {
clearInterval(interval);
throw ex;
}
}, 100);
};
}"
;
sb.AppendLine(
"<script type=\"text/javascript\" defer=\"defer\">"
);
sb.AppendLine(executeOn);
sb.AppendLine(
@"executeOn(""typeof SyntaxHighlighter !== 'undefined' "", function() {"
);
if
(Options !=
null
)
{
if
(Options.GetSingleValue(
"gutter"
).ToLowerInvariant() ==
"false"
)
sb.AppendLine(GetOption(
"gutter"
));
if
(Options.GetSingleValue(
"smart-tabs"
).ToLowerInvariant() ==
"false"
)
sb.AppendLine(GetOption(
"smart-tabs"
));
if
(Options.GetSingleValue(
"auto-links"
).ToLowerInvariant() ==
"false"
)
sb.AppendLine(GetOption(
"auto-links"
));
if
(Options.GetSingleValue(
"collapse"
).ToLowerInvariant() ==
"true"
)
sb.AppendLine(GetOption(
"collapse"
));
if
(Options.GetSingleValue(
"toolbar"
).ToLowerInvariant() ==
"false"
)
sb.AppendLine(GetOption(
"toolbar"
));
if
(Options.GetSingleValue(
"tab-size"
) !=
"4"
)
sb.AppendLine(GetOption(
"tab-size"
));
}
sb.AppendLine(
@"
executeOn(""document.readyState === 'loaded' || document.readyState === 'complete'"", function() {
SyntaxHighlighter.all();
});"
);
sb.AppendLine(
@"});"
);
sb.AppendLine(
"</script>"
);
page.ClientScript.RegisterStartupScript(page.GetType(),
"SyntaxHighlighter"
, sb.ToString(),
false
);
}
private
static
string
GetUrl(
string
folder,
string
url)
{
string
s = HttpContext.Current.Server.UrlPathEncode(
string
.Format(
"{0}{1}"
, folder, url));
if
(!folder.ToLowerInvariant().Contains(
"http:"
) && !folder.ToLowerInvariant().Contains(
"https://"
))
s = Utils.ApplicationRelativeWebRoot + s;
return
s;
}
#endregion
#region Private methods
private
static
void
InitSettings()
{
var
s = Options;
}
static
string
OptionsHelp()
{
StringBuilder sb =
new
StringBuilder();
sb.AppendLine(
"<p><b>cdnScriptsPath</b>: Allows you to load the SyntaxHighlighter script from a CDN. Leave empty for local files</p>"
);
sb.AppendLine(
"<p><b>cdnStylesPath</b>: Allows you to load the SyntaxHighlighter styles from a CDN. Leave empty for local files</p>"
);
sb.AppendLine(
"<p><b>auto-links</b>: Allows you to turn detection of links in the highlighted element on and off. If the option is turned off, URLs won't be clickable.</p>"
);
sb.AppendLine(
"<p><b>collapse</b>: Allows you to force highlighted elements on the page to be collapsed by default.</p>"
);
sb.AppendLine(
"<p><b>gutter</b>: Allows you to turn gutter with line numbers on and off.</p>"
);
sb.AppendLine(
"<p><b>smart-tabs</b>: Allows you to turn smart tabs feature on and off.</p>"
);
sb.AppendLine(
"<p><b>tab-size</b>: Allows you to adjust tab size.</p>"
);
sb.AppendLine(
"<p><b>toolbar</b>: Toggles toolbar on/off.</p>"
);
return
sb.ToString();
}
static
string
GetOption(
string
opt)
{
if
(Options !=
null
)
{
string
pattern =
"\tSyntaxHighlighter.defaults['{0}'] = {1};"
;
string
val = Options.GetSingleValue(opt).ToLowerInvariant();
return
string
.Format(pattern, opt, val);
}
return
""
;
}
static
string
ScriptsFolder()
{
if
(Options !=
null
)
{
if
(!String.IsNullOrEmpty(Options.GetSingleValue(
"cdnScriptsPath"
)))
return
Options.GetSingleValue(
"cdnScriptsPath"
);
else
return
"Scripts/syntaxhighlighter/"
;
}
return
""
;
}
static
string
StylesFolder()
{
if
(Options !=
null
)
{
if
(!String.IsNullOrEmpty(Options.GetSingleValue(
"cdnStylesPath"
)))
return
Options.GetSingleValue(
"cdnStylesPath"
);
else
return
"Styles/syntaxhighlighter/"
;
}
return
""
;
}
#endregion
}