部落格的文章我一直是用 Markdown Monster 寫完後,直接 Ctrl + Shift + C
,Markdown Monster 會直接幫我將文章轉成 HTML 內容寫入到剪貼薄中,接著在點部落的編輯器上切換原始碼,再把 HTML 內容貼上去,但是最近點部落的編輯器改版了,沒辦法直接貼上 HTML 原始碼,可是 Markdown Monster 複製的 HTML 內容居然貼得上去,這其中必有緣故。
HTML 剪貼薄格式
一查之下才發現,原來我們寫入到剪貼薄的內容是有格式的,HTML 就是其中之一,但是也不是說將 HTML 原始碼寫入到剪貼薄中,就會被判斷是 HTML,我們必須將 HTML 原始碼照著一定的格式寫入到剪貼薄中,才會是真的 HTML 格式,不然就只是一般的純文字而已,而這個 HTML 格式看起來就像下面這樣。
Version:0.9
StartHTML:000000149
EndHTML:000000749
StartFragment:000000204
EndFragment:000000713
StartSelection:000000204
EndSelection:000000713
<!DOCTYPE html>
<html>
<body>
<!--StartFragment--><p>部落格的文章我一直是用 <a href="https://markdownmonster.west-wind.com/">Markdown Monster</a> 寫完後,直接 <code>Ctrl + Shift + C</code>,Markdown Monster 會直接幫我將文章轉成 HTML 內容,複製到剪貼薄中,然後我再直接把 HTML 內容貼到<a href="https://dotblogs.com.tw/">點部落</a>上,最近點部落的編輯器改版了,沒辦法直接貼上 HTML 原始碼,但是 Markdown Monster 複製的 HTML 內容居然貼得上去,這其中必有緣故。</p><!--EndFragment-->
</body>
</html>
Version
:固定就填 0.9StartHTML/EndHTML
:HTML 內容開始及結束的byte 索引位置
,從上面的例子來看,開始就是<!DOCTYPE html>
的<
,結束就是</html>
的>
。StartFragment/EndFragment
:實際被複製的 HTML 內容開始及結束的 byte 索引位置,從上面的例子來看,就是<p>部落格的文章
的<
,以及必有緣故。</p>
的>
,而且實際被複製的 HTML 內容應該用<!--StartFragment--><!--EndFragment-->
包起來。StartSelection/EndSelection
:額外包含的一些資訊,目前沒用到,填的值跟 StartFragment/EndFragment 一樣就行了。
Clipboard
在 C# 要寫入資料到剪貼薄中,用的是 Clipboard 類別,我們要寫入 HTML 格式的文字還需要 DataObject 類別,接著我們就照著格式把我們要的 HTML 內容兜好。
var html = @"<p>部落格的文章我一直是用 <a href=""https://markdownmonster.west-wind.com/"">Markdown Monster</a> 寫完後,直接 <code>Ctrl + Shift + C</code>,Markdown Monster 會直接幫我將文章轉成 HTML 內容,複製到剪貼薄中,然後我再直接把 HTML 內容貼到<a href=""https://dotblogs.com.tw/"">點部落</a>上,最近點部落的編輯器改版了,沒辦法直接貼上 HTML 原始碼,但是 Markdown Monster 複製的 HTML 內容居然貼得上去,這其中必有緣故。</p>";
var header = @"Version:0.9
StartHTML:<<<<<<<<1
EndHTML:<<<<<<<<2
StartFragment:<<<<<<<<3
EndFragment:<<<<<<<<4
StartSelection:<<<<<<<<3
EndSelection:<<<<<<<<4";
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine(header);
stringBuilder.AppendLine("<!DOCTYPE html>");
stringBuilder.AppendLine("<html>");
stringBuilder.AppendLine("<body>");
stringBuilder.Append("<!--StartFragment-->");
var fragmentStart = stringBuilder.GetByteCount();
stringBuilder.Append(html);
var fragmentEnd = stringBuilder.GetByteCount();
stringBuilder.AppendLine("<!--EndFragment-->");
stringBuilder.AppendLine("</body>");
stringBuilder.Append("</html>");
stringBuilder.Replace("<<<<<<<<1", header.Length.ToString("D9"));
stringBuilder.Replace("<<<<<<<<2", stringBuilder.GetByteCount().ToString("D9"));
stringBuilder.Replace("<<<<<<<<3", fragmentStart.ToString("D9"));
stringBuilder.Replace("<<<<<<<<4", fragmentEnd.ToString("D9"));
var dataObject = new DataObject();
dataObject.SetData(DataFormats.Html, stringBuilder.ToString());
dataObject.SetData(DataFormats.Text, html);
dataObject.SetData(DataFormats.UnicodeText, html);
Clipboard.SetDataObject(dataObject, true);
其中 DataObject 需要再指定 Text
及 UnicodeText
格式的內容,因為剪貼薄的貼上功能,其實是會根據要貼上去的地方,去判斷該貼上哪一種格式的內容,如果我們不指定這兩種格式的內容,像是貼上 Notepad(記事本)的時候就不會出現任何文字。
程式撰寫好之後,我們就來跑跑看,可以看到只是單純地複製 HTML 文字到點部落的編輯器,就只是純文字而已,但是透過指定的 HTML 格式寫入剪貼薄之後,貼上去之後就呈現 HTML 效果的內容。