在CSDN博客發表帶語法高亮C++代碼的小技巧
雖然CSDN的Blog有“插入代碼”的功能,但是不支持C++。
CSDN的編輯器使用了開源的FCKEditor。雖然它支持從Word中粘貼帶格式的文本,但是從其它地方則不行。比如直接從VS2005拷貝,就無法正確識別格式。
但是從Word拷貝有一個問題 ,代碼的行間距會變得特別大。經過研究之後,發現瞭解決方法。
(要從VS中拷貝語法高亮的代碼可以使用我寫的小工具CSDN Blogger)
沒仔細研究過CSDN的編輯器是如何處理Word中拷貝過來的數據的。我是直接讀取Word放到剪貼板上的“HTML Format”格式的文本,並做了處理,以消除行間距過大的問題。
(我使用的是Word2000,所以下面的處理僅針對這一特定版本。其它版本可以類似處理)
1、首先從剪貼板獲取“HTML Format”格式的文本,注意到它是UTF_8編碼的,所以需要進行一次轉換
2、將其中的“<p>...</p>”標記替換爲“</br>”,這樣間距就正常了
3、將代碼中的‘/xA0’替換爲空格(Word中使用‘/xA0’來表示起始空格)
4、將空格替換爲HTML中對應的“ ”
#pragma warning(disable: 4819)
#include "boost/scoped_array.hpp"
using boost::scoped_array;
#include "boost/algorithm/string.hpp"
#include <string>
using std::wstring;
#include <cstdio>
#include <cstring>
#include <windows.h>
wstring GetWordText()
{
wstring ret;
BOOL bl=::OpenClipboard(NULL);
if (!bl) return ret;
UINT id=::RegisterClipboardFormat("HTML Format");
if (id)
{
HANDLE hr=::GetClipboardData(id);
if (hr)
{
try
{
const char *temp=(const char *)hr;
size_t len=strlen(temp)+1;
scoped_array<char> str(new char[len]);
memcpy(str.get(),temp,len);
scoped_array<wchar_t> strW(new wchar_t[len]);
::MultiByteToWideChar(CP_UTF8,0,str.get(),static_cast<int>(len),strW.get(),static_cast<int>(len));
ret=strW.get();
}
catch (std::bad_alloc &)
{
}
}
}
::CloseClipboard();
return ret;
}
int main()
{
std::locale::global(std::locale("",std::locale::ctype));
wstring str(GetWordText());
wstring::size_type pos;
pos=str.find(L"<!--StartFragment-->");
if (pos!=wstring::npos)
{
str.erase(0,pos+21);
}
boost::algorithm::replace_all(str,L"<p class=MsoNormal>",L"");
boost::algorithm::replace_all(str,L"<p class=MsoNormal align=left style='text-align:left;mso-layout-grid-align:/r/nnone;text-autospace:none'>",L"");
boost::algorithm::replace_all(str,L"</p>",L"</br>");
boost::algorithm::replace_all(str,L"/xA0",L" ");
boost::algorithm::replace_all(str,L" ",L" ");
pos=str.find(L"<!--EndFragment-->");
if (pos!=wstring::npos)
{
str.erase(pos);
}
}
不過這樣還是很不方便,不知道有沒有更好的解決方案?另外就是Word中的空格或者Tab拷貝到編輯器之後,空格數目總是和原來的不對應
CSDN的編輯器使用了開源的FCKEditor。雖然它支持從Word中粘貼帶格式的文本,但是從其它地方則不行。比如直接從VS2005拷貝,就無法正確識別格式。
但是從Word拷貝有一個問題 ,代碼的行間距會變得特別大。經過研究之後,發現瞭解決方法。
(要從VS中拷貝語法高亮的代碼可以使用我寫的小工具CSDN Blogger)
沒仔細研究過CSDN的編輯器是如何處理Word中拷貝過來的數據的。我是直接讀取Word放到剪貼板上的“HTML Format”格式的文本,並做了處理,以消除行間距過大的問題。
(我使用的是Word2000,所以下面的處理僅針對這一特定版本。其它版本可以類似處理)
1、首先從剪貼板獲取“HTML Format”格式的文本,注意到它是UTF_8編碼的,所以需要進行一次轉換
2、將其中的“<p>...</p>”標記替換爲“</br>”,這樣間距就正常了
3、將代碼中的‘/xA0’替換爲空格(Word中使用‘/xA0’來表示起始空格)
4、將空格替換爲HTML中對應的“ ”
#pragma warning(disable: 4819)
#include "boost/scoped_array.hpp"
using boost::scoped_array;
#include "boost/algorithm/string.hpp"
#include <string>
using std::wstring;
#include <cstdio>
#include <cstring>
#include <windows.h>
wstring GetWordText()
{
wstring ret;
BOOL bl=::OpenClipboard(NULL);
if (!bl) return ret;
UINT id=::RegisterClipboardFormat("HTML Format");
if (id)
{
HANDLE hr=::GetClipboardData(id);
if (hr)
{
try
{
const char *temp=(const char *)hr;
size_t len=strlen(temp)+1;
scoped_array<char> str(new char[len]);
memcpy(str.get(),temp,len);
scoped_array<wchar_t> strW(new wchar_t[len]);
::MultiByteToWideChar(CP_UTF8,0,str.get(),static_cast<int>(len),strW.get(),static_cast<int>(len));
ret=strW.get();
}
catch (std::bad_alloc &)
{
}
}
}
::CloseClipboard();
return ret;
}
int main()
{
std::locale::global(std::locale("",std::locale::ctype));
wstring str(GetWordText());
wstring::size_type pos;
pos=str.find(L"<!--StartFragment-->");
if (pos!=wstring::npos)
{
str.erase(0,pos+21);
}
boost::algorithm::replace_all(str,L"<p class=MsoNormal>",L"");
boost::algorithm::replace_all(str,L"<p class=MsoNormal align=left style='text-align:left;mso-layout-grid-align:/r/nnone;text-autospace:none'>",L"");
boost::algorithm::replace_all(str,L"</p>",L"</br>");
boost::algorithm::replace_all(str,L"/xA0",L" ");
boost::algorithm::replace_all(str,L" ",L" ");
pos=str.find(L"<!--EndFragment-->");
if (pos!=wstring::npos)
{
str.erase(pos);
}
}
不過這樣還是很不方便,不知道有沒有更好的解決方案?另外就是Word中的空格或者Tab拷貝到編輯器之後,空格數目總是和原來的不對應
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.