最近在準備開發教學投影片,有大量從Visual Studio剪貼程式碼範例到PowerPoint的需求,遇到一個大問題:從Visual Studio複製程式碼再貼到PowerPoint時,語法顏色有被保留,但換行消失,排版全亂,讓人極度困擾。
想起VS2010推出時也有類似的剪貼簿亂碼問題,當時寫了個小工具自力救濟。這次面對的情況類似,理應可如法炮製,便花了點時間研究,發現Visual Studio複製到剪貼薄的內容包含HTML格式,使用Regex將原始碼中的\n換成<br />,在PowerPoint就能忠實反應原有的換行與排版。以修正版HTML換掉原本的剪貼薄內容,惱人的換行問題便可迎刃而解。
修正剪貼簿內容的核心邏輯只有短短幾行,如下所示:
privatevoid btnAddLineBreaks_Click(object sender, EventArgs e)
{
IDataObject dataObject = Clipboard.GetDataObject();
if (!dataObject.GetDataPresent(DataFormats.Html)) return;
string html = dataObject.GetData(DataFormats.Html) asstring;
string endFragmentTag = "EndFragment";
if (!html.Contains(endFragmentTag)) return;
string pattern = endFragmentTag + ":(?<n>[0-9]{8})";
var findLen = Regex.Match(html, pattern);
if (!findLen.Success) return;
var len = int.Parse(findLen.Groups["n"].Value);
var htmlStart = html.IndexOf("<HTML");
html = Regex.Replace(html, "\n", (m) =>
{
if (m.Index < htmlStart) return m.Value;
len += 6;
return m.Value + "<br />";
});
//change EndFragment and EndSelection
string origLenText = findLen.Value;
html = html.Replace(
origLenText,
string.Format("{0}:{1:00000000}", endFragmentTag, len))
.Replace(
origLenText.Replace("Fragment", "Selection"),
string.Format("EndSelection:{0:00000000}", len));
DataObject newDataObject = new DataObject();
newDataObject.SetData(DataFormats.Html, html);
newDataObject.SetData(DataFormats.Text,
dataObject.GetData(DataFormats.Text) asstring);
Clipboard.SetDataObject(newDataObject, true);
}
以下是動畫展示。原本從VS2015複製程式碼,貼到PowerPoint時換行符號會不見,叫出自製小工具,複製程式碼後先按「Add Line Breaks」再貼到PowerPoint,換行及排版便能完整保留。註:以上程式碼丟進WinForm按鈕事件就可運作,如果嫌麻煩,我在FB社團放了一個現成版本。
另外,將程式碼貼到內容區塊的做法雖然能保留換行,但原有底色及文字顏色會被PowerPoint置換,若想讓Visual Studio程式碼樣式在投影片原汁原味重現,我找到一個好方法:不要將程式碼貼入中央的內容區塊,改將滑鼠移到投影片的空白處透過右鍵選單貼上(或將焦點自內容區塊移開再按Ctrl-V),程式碼會被貼到投影片最上方,程式碼樣式被完整保留,但高度未依內容自動調整。此時只要隨意更動區塊寬度,高度就會依內容自動縮放,接著Visual Studio程式碼就在簡報上完美重現囉!