Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to add Code Snippets With Syntax Highlighting support (without need for extension) #658

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/managed/OpenLiveWriter.HtmlEditor/CodeHighlighter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;

namespace OpenLiveWriter.HtmlEditor
{
public class CodeHighlighter
{
private const int TAB_SIZE = 4;

private const string PRE_OPEN = "<pre>";
private const string PRE_CLOSE = "</pre>";
private const string PRE_OPEN_STYLED = "<pre class=\"prettyprint\">";
private const string PRETTIFY_SCRIPT_NAME = "run_prettify.js";
private const string DEFAULT_SKIN = CodeHighlighterSkins.Sunburst;

private static readonly string _prettifyScript =
$"<script src=\"https://cdn.rawgit.com/google/code-prettify/master/loader/{PRETTIFY_SCRIPT_NAME}?skin={DEFAULT_SKIN}\"></script>";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://rawgit.com/ is currently in sunset and will be shut-down by October. Whatever service is used instead, the user should be informed that a third-party script is being inserted into their site, and a third-party service is used to fetch it. Use of subresource integrity would also be desired.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this site that produces HTML for pretty printing code, and it has an API you can call:

http://hilite.me/

I've not yet worked out what this PR is actually doing, so I haven't any ideas on how to use it to update this PR, but thought I'd mention it in case some one else can use it to update this PR, or else explain what this code is doing so that I can attempt to update it.


public static string StyledHtml(string htmlText, string innerHtml)
{
// Using Google's prettifier (https://github.com/google/code-prettify)
htmlText = SwapTabsForSpaces(htmlText);
htmlText = ReplaceLineEndings(htmlText);
htmlText = RemoveCode(htmlText, PRE_OPEN_STYLED, PRE_CLOSE);
htmlText = RemoveCode(htmlText, PRE_OPEN, PRE_CLOSE);

bool addScript = ShouldAddJsScript(innerHtml);
string script = addScript ? _prettifyScript : string.Empty;

string styledHtml = $"{script}{PRE_OPEN_STYLED}{htmlText}{PRE_CLOSE}";
return styledHtml;
}

private static string ReplaceLineEndings(string htmlText)
{
htmlText = htmlText.Replace(Environment.NewLine, "");
return htmlText;
}

private static string SwapTabsForSpaces(string text)
{
return text.Replace("\t", " ".PadLeft(TAB_SIZE));
}

private static bool ShouldAddJsScript(string innerHtml)
{
var body = innerHtml.ToLowerInvariant();
if (body.Contains(PRETTIFY_SCRIPT_NAME))
{
return false;
}

return true;
}

private static string RemoveCode(string htmlText, string open, string close)
{
string htmlL = htmlText.ToLowerInvariant();
int index = htmlL.IndexOf(open, StringComparison.InvariantCulture);
if (index >= 0)
{
htmlText = htmlText.Remove(index, open.Length);
htmlL = htmlText.ToLowerInvariant();

index = htmlL.IndexOf(close, StringComparison.InvariantCulture);
if (index >= 0)
{
htmlText = htmlText.Remove(index, close.Length);
}

}

return htmlText;
}
}

// To be used when adding support for skins
// For example: https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=sunburst
// All Styles: https://rawgit.com/google/code-prettify/master/styles/index.html
public static class CodeHighlighterSkins
{
public const string Default = "default";
public const string Sunburst = "sunburst";
public const string SonsOfObsidian = "sons-of-obsidian";
public const string Desert = "desert";
}
}
31 changes: 31 additions & 0 deletions src/managed/OpenLiveWriter.HtmlEditor/HtmlEditorControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4551,6 +4551,37 @@ void IHtmlEditorCommandSource.ApplyOutdent()
ExecuteBlockCommand(new CommandExecutor(GetMshtmlCommand(IDM.OUTDENT).Execute));
}

bool IHtmlEditorCommandSource.CanInsertCode
{
get
{
return Editable;
}
}

void IHtmlEditorCommandSource.InsertCode()
{
using (new WaitCursor())
{
var range = SelectedMarkupRange;
string htmlText = range?.HtmlText;
if (htmlText != null)
{
IUndoUnit undoUnit = CreateUndoUnit();
using (undoUnit)
{
IHTMLDocument2 document = HTMLDocument;
var styledHtml = CodeHighlighter.StyledHtml(htmlText, document.body.innerHTML);

InsertHtml(range.Start, range.End, styledHtml);

// commit the change
undoUnit.Commit();
}
}
}
}

bool IHtmlEditorCommandSource.CanInsertLink
{
get
Expand Down
14 changes: 14 additions & 0 deletions src/managed/OpenLiveWriter.HtmlEditor/HtmlSourceEditorControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,20 @@ void IHtmlEditorCommandSource.ApplyOutdent()
// not supported
}

bool IHtmlEditorCommandSource.CanInsertCode
{
get
{
// not suppported
return false;
}
}

void IHtmlEditorCommandSource.InsertCode()
{
// not supported
}

bool IHtmlEditorCommandSource.CanInsertLink
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public interface IHtmlEditorCommandSource : ISimpleTextEditorCommandSource
void ApplyBlockquote();
bool SelectionBlockquoted { get; }

bool CanInsertCode { get; }
void InsertCode();

bool CanInsertLink { get; }
void InsertLink();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<Compile Include="..\GlobalAssemblyInfo.cs" />
<Compile Include="BasicHtmlGenerationService.cs" />
<Compile Include="BoldApplier.cs" />
<Compile Include="CodeHighlighter.cs" />
<Compile Include="Controls\HtmlStylePicker.cs">
<SubType>UserControl</SubType>
</Compile>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/managed/OpenLiveWriter.Localization/CommandId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public enum CommandId
ImageTilt = 1085,
Indent = 1046,
InsertClearBreak = 1039,
InsertCode = 1041,
InsertColumnLeft = 23377,
InsertColumnRight = 23378,
InsertEmoticon = 1102,
Expand Down
20 changes: 20 additions & 0 deletions src/managed/OpenLiveWriter.Localization/Images.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/managed/OpenLiveWriter.Localization/Images.resx
Original file line number Diff line number Diff line change
Expand Up @@ -4986,4 +4986,10 @@
<data name="VideoAspectRatioGroup_SmallImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>commandbitmaps\videostandardaspectratio_smallimage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="InsertCode_LargeImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>CommandBitmaps\InsertCode.LargeImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="InsertCode_SmallImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>CommandBitmaps\InsertCode.SmallImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
<None Include="CommandBitmaps\AddTagProvider.LargeImage.png" />
<None Include="CommandBitmaps\AddTagProvider.SmallImage.png" />
<None Include="CommandBitmaps\AddWeblog.SmallImage.png" />
<None Include="CommandBitmaps\InsertCode.LargeImage.png" />
<None Include="CommandBitmaps\InsertCode.SmallImage.png" />
<Content Include="CommandBitmaps\CustomSizeGallery_LargeImage.png" />
<Content Include="CommandBitmaps\CustomSizeGallery_SmallImage.png" />
<Content Include="CommandBitmaps\Effects_Black_and_White.png" />
Expand Down
9 changes: 9 additions & 0 deletions src/managed/OpenLiveWriter.Localization/Properties.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,15 @@
<data name="Command.InsertClearBreak.TooltipDescription" xml:space="preserve">
<value>Insert a break after a picture to prevent text wrapping.</value>
<comment>Button to insert a break after an aligned image to prevent text wrapping.</comment></data>
<data name="Command.InsertCode.Keytip" xml:space="preserve">
<value>IC</value>
</data>
<data name="Command.InsertCode.LabelTitle" xml:space="preserve">
<value>Code</value>
</data>
<data name="Command.InsertCode.TooltipDescription" xml:space="preserve">
<value>Transform to code with syntax highlighting.</value>
</data>
<data name="Command.InsertColumnLeft.Keytip" xml:space="preserve">
<value>IL</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3381,6 +3381,22 @@ public void ApplyOutdent()
_currentEditor.CommandSource.ApplyOutdent();
}

public bool CanInsertCode
{
get
{
return CurrentEditingMode != EditingMode.PlainText
&& !IsEditFieldSelected
&& _currentEditor != null
&& _currentEditor.CommandSource.CanInsertCode;
}
}

public void InsertCode()
{
_currentEditor.CommandSource.InsertCode();
}

public bool CanInsertLink
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ private void InitializeCommands()
InitializeCommand(new SuperscriptCommand());
InitializeCommand(new SubscriptCommand());
InitializeCommand(new ClearFormattingCommand());
InitializeCommand(new InsertCodeCommand());

commandFontSize = new FontSizeCommand();
CommandManager.Add(commandFontSize);
Expand Down Expand Up @@ -1418,6 +1419,21 @@ public override void Manage()
}
}

private class InsertCodeCommand : TextEditingCommand
{
public override CommandId CommandId { get { return CommandId.InsertCode; } }

protected override void Execute()
{
PostEditor.InsertCode();
}

public override void Manage()
{
Enabled = PostEditor.CanInsertCode;
}
}

private class InsertLinkCommand : TextEditingCommand
{
public override CommandId CommandId { get { return CommandId.InsertLink; } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
<ItemGroup>
<ResourceCompile Include="OpenLiveWriter.Ribbon.rc" />
</ItemGroup>
<ItemGroup>
<Xml Include="Ribbon.xml" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(RepoRoot)\writer.build.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
4 changes: 3 additions & 1 deletion src/unmanaged/OpenLiveWriter.Ribbon/Ribbon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<Command Name="cmdFormatImageSaveSettings" Keytip="DS" LabelTitle="Set to default" TooltipTitle="Set to default" TooltipDescription="Set the alignment, margin, picture style, and properties of this picture as the default for other pictures." Symbol="cmdFormatImageSaveSettings" Id="1100" Comment="ImageContextTabGroup-FormatImageTab-FormatImageSettingsGroup-FormatImageSaveSettings"/>
<Command Name="cmdFormatImageRevertSettings" Keytip="DR" LabelTitle="Revert to original" TooltipTitle="Revert to original" TooltipDescription="Revert to the original version of this picture." Symbol="cmdFormatImageRevertSettings" Id="1101" Comment="ImageContextTabGroup-FormatImageTab-FormatImageSettingsGroup-FormatImageRevertSettings"/>
<Command Name="cmdInsertEmoticon" LabelTitle="Emoticon" TooltipTitle="Emoticon" TooltipDescription="Insert an emoticon." Symbol="cmdInsertEmoticon" Id="1102" Comment="InsertTab-MediaGroup-InsertEmoticon"/>
<Command Name="cmdInsertCode" LabelTitle="Code" TooltipTitle="Code" TooltipDescription="Insert code snippet." Symbol="cmdInsertCode" Id="1041" Comment="InsertTab-MediaGroup-InsertCode"/>
<Command Name="cmdCustomSizeSmall" LabelTitle="&amp;Small" TooltipTitle="Small" Symbol="cmdCustomSizeSmall" Id="1103" Comment="ImageContextTabGroup-FormatImageTab-FormatImageSizeGroup-CustomSizeGallery-CustomSizeSmall"/>
<Command Name="cmdCustomSizeMedium" LabelTitle="&amp;Medium" TooltipTitle="Medium" Symbol="cmdCustomSizeMedium" Id="1104" Comment="ImageContextTabGroup-FormatImageTab-FormatImageSizeGroup-CustomSizeGallery-CustomSizeMedium"/>
<Command Name="cmdCustomSizeLarge" LabelTitle="&amp;Large" TooltipTitle="Large" Symbol="cmdCustomSizeLarge" Id="1105" Comment="ImageContextTabGroup-FormatImageTab-FormatImageSizeGroup-CustomSizeGallery-CustomSizeLarge"/>
Expand Down Expand Up @@ -576,7 +577,7 @@
<Group CommandName="cmdTablesGroup" SizeDefinition="OneButton" ApplicationModes="0">
<Button CommandName="cmdInsertTable"/>
</Group>
<Group CommandName="cmdMediaGroup" SizeDefinition="SixButtons" ApplicationModes="0">
<Group CommandName="cmdMediaGroup" SizeDefinition="SevenButtons" ApplicationModes="0">
<Button CommandName="cmdInsertLink"/>
<DropDownButton CommandName="cmdInsertImageSplit">
<MenuGroup>
Expand All @@ -598,6 +599,7 @@
<FlowMenuLayout Columns="10" Gripper="None"/>
</DropDownGallery.MenuLayout>
</DropDownGallery>
<Button CommandName="cmdInsertCode"/>
</Group>
<Group CommandName="cmdPluginsGroup" SizeDefinition="TwoButtons" ApplicationModes="4">
<!-- No plugins gallery if there are no installed plugins. -->
Expand Down