在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拷贝到编辑器之后,空格数目总是和原来的不对应

你可能感兴趣的:(Algorithm,html,C++,String,Blog,fckeditor)