在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中對應的“&nbsp;”

#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"&nbsp;&nbsp;&nbsp;&nbsp;");
    pos=str.find(L"<!--EndFragment-->");
    if (pos!=wstring::npos)
    {
        str.erase(pos);
    }
}

不過這樣還是很不方便,不知道有沒有更好的解決方案?另外就是Word中的空格或者Tab拷貝到編輯器之後,空格數目總是和原來的不對應
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章