Skip to content

Instantly share code, notes, and snippets.

@pcrama
Last active December 2, 2021 10:53
Show Gist options
  • Save pcrama/9dd5c3a8ee94370a443b360484333558 to your computer and use it in GitHub Desktop.
Save pcrama/9dd5c3a8ee94370a443b360484333558 to your computer and use it in GitHub Desktop.
Sets clipboard content to HTML (to export org mode as rich text to the clipboard)
/* Compiling this needs a reference to the PresentationCore dll:
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe" "/reference:c:\windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationCore.dll" "/out:cliphtml.exe" cliphtml.cs
*/
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows; // Needed to access the clipboard.
namespace SetClipBoardToHtml
{
/// <summary>
/// Set clipboard to HTML data (as rich/formatted text), assuming UTF8 input.
/// </summary>
class SetClipBoardToHtml
{
public static readonly Encoding AssumedInputEncoding = Encoding.UTF8;
[STAThread]
static void Main(string[] args)
{
string input = "";
string sourceName = "temp.htm"; // will be overridden if HTML source is a file
if (args.Length == 0
|| (args.Length == 1 && args[0] == "-"))
{
Console.InputEncoding = AssumedInputEncoding;
input = Console.In.ReadToEnd();
}
else if (args.Any(IsHelpArgument))
{
usage();
}
else if (args.Length == 1)
{
// Read from file
sourceName = args[0];
using (StreamReader streamReader = new StreamReader(sourceName, AssumedInputEncoding))
{
input = streamReader.ReadToEnd();
}
}
else if ((args.Length > 1) && (args[0] == "-t"))
{
// Assemble from command line args
for (int i = 1; i < args.Length; ++i)
{
input += ((1 == i) ? "" : " ") + args[i];
}
}
else
{
usage();
}
if ((null != input) && ("" != input)) {
Clipboard.SetText(BuildContent(input, sourceName),
TextDataFormat.Html);
Clipboard.Flush();
}
}
/* Clipboard content needs to contain some meta-data, see
https://blogs.msdn.microsoft.com/jmstall/2007/01/21/copying-html-on-the-clipboard/
Version:0.9
StartHTML:00000185
EndHTML:00000260
StartFragment:00000219
EndFragment:00000224
SourceURL:https://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard.aspx
<html><body>
<!--StartFragment-->abcde<!--EndFragment-->
</body>
</html>
*/
static string BuildContent(string fragment, string sourceName)
{
string[] HEADERS = {
"Version:0.9\r\nStartHTML:",
"\r\nEndHTML:",
"\r\nStartFragment:",
"\r\nEndFragment:",
};
const int VAL_LEN = 8;
string MIDDLE = String.Format(
"\r\nSourceURL:{0}\r\n<html><body>\r\n<!--StartFragment-->",
sourceName);
const string TRAILER = "<!--EndFragment-->\r\n</body>\r\n</html>";
int header_len = 0;
for (int i = 0; i < HEADERS.Length; ++i) {
header_len += HEADERS[i].Length + VAL_LEN;
}
int START_FRAGMENT = header_len + MIDDLE.Length;
int END_FRAGMENT = START_FRAGMENT + fragment.Length;
int TOTAL_LEN = END_FRAGMENT + TRAILER.Length;
int[] VALUES = { header_len, TOTAL_LEN, START_FRAGMENT, END_FRAGMENT };
string FMT_HEAD = "{0}{1:" + String.Format("{0}", VAL_LEN) + "}";
string result = "";
for (int i = 0; i < VALUES.Length; ++i) {
result += String.Format(FMT_HEAD, HEADERS[i], VALUES[i]);
}
result += String.Format(FMT_HEAD, HEADERS[VALUES.Length - 1], "temp.htm");
result += MIDDLE + fragment + TRAILER;
return result;
}
static bool IsHelpArgument(string arg)
{
return string.Equals(arg, "-h", StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(arg, "--help", StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(arg, "/?", StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(arg, "-?", StringComparison.InvariantCultureIgnoreCase);
}
static void usage()
{
Console.WriteLine(
"cliphtml filename ==> file content to clipboard (as HTML, rich text)\n" +
"cliphtml -t ... ==> Command line to clipboard\n" +
"cliphtml [-] ==> standard input to clipboard\n" +
"cliphtml [-h|--help|-?|/?] ==> this help text"
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment