//***************************************************************************** // SrcToHtmlPre.cpp // C, C++ のソースのコメント行やキーワードをカラー表示するためのHTMLタグを生成。 // 呼ぶ手順は(HTMLファイルの生成手順)は、末尾の example を参照 // キーワードの種類やチェック方法(/* */も含めて)は、厳密なものではありません。 //***************************************************************************** #include "stdafx.h" int SrcToHtmlPre( const char* ps , char* pd , int slen ) ; BYTE* SearchTextSimple( BYTE* hStartP , int blen , LPCSTR lpszFind, BOOL bNext, BOOL bCase ) ; int IsKeyword( const char* pb , int slen ) ; #define MAXCCPPKEYWORDLEN 25 struct ccppkeywordtblstruct { int len ; BYTE str[MAXCCPPKEYWORDLEN+1] ; } ; static struct ccppkeywordtblstruct cppktbl[] = { {5,"__asm"} , {10,"__fastcall"} , {6,"__self"} , {4,"auto"} , {5,"float"} , {9,"__segment"} , {7,"__based"} , {3,"for"} , {9,"__segname"} , {5,"break"} , {9,"__fortran"} , {5,"short"} , {4,"case"} , {4,"goto"} , {6,"signed"} , {7,"__cdecl"} , {6,"__huge"} , {6,"sizeof"} , {4,"char"} , {2,"if"} , {6,"static"} , {5,"const"} , {8,"__inline"} , {6,"struct"} , {8,"continue"} , {3,"int"} , {6,"switch"} , {7,"default"} , {11,"__interrupt"} , {7,"typedef"} ,{2,"do"} , {8,"__loadds"} , {5,"union"} , {6,"double"} , {4,"long"} , {8,"unsigned"} , {4,"else"} ,{6,"__near"} , {4,"void"} , {4,"enum"} , {8,"__pascal"} , {8,"volatile"} , {8,"__export"} , {8,"register"} , {5,"while"} , {6,"extern"} , {6,"return"} , {5,"__far"} , {10,"__saveregs"} , {7,"#define"} , {6,"#error"} , {8,"#include"} , {5,"#elif"} , {3,"#if"} , {5,"#line"} , {5,"#else"} ,{6,"#ifdef"} , {7,"#pragma"} , {6,"#endif"} , {7,"#ifndef"} , {6,"#undef"} , {6,"_based"} , {8,"_segname"} , {7,"fortran"} , {8,"_fortran"} , {6,"_cdecl"} , {5,"cdecl"} , {4,"huge"} , {5,"_huge"} , {7,"_inline"} , {9,"interrupt"} , {10,"_interrupt"} , {7,"_loadds"} , {4,"near"} , {5,"_near"} , {6,"pascal"} , {7,"_pascal"} , {7,"_export"} , {3,"far"} , {4,"_far"} , {9,"_saveregs"} , {5,"class"} , {8,"operator"} , {3,"try"} , {6,"delete"} , {7,"private"} , {7,"virtual"} , {6,"friend"} , {9,"protected"} , {22,"__multiple_inheritance"} , {6,"inline"} , {6,"public"} , {20,"__single_inheritance"} , {3,"new"} , {4,"this"} , {21,"__virtual_inheritance"} } ; //***************************************************************************** // 機能 :c, c++ のソースのコメント行やキーワードをカラー表示するためのHTMLタグを生成 // 注意 :ps[slen]はアクセス可能前提 // 呼ぶ手順は(HTMLファイルの生成手順)は、末尾の example を参照 //***************************************************************************** int SrcToHtmlPre( const char* ps , char* pd , int slen ) { int i ; int j ; for ( i = 0 , j = 0 ; i < slen ; ) { BYTE bt = (BYTE)ps[i] ; if ( _ismbblead( bt ) ) { pd[j++] = ps[i++] ; pd[j++] = ps[i++] ; continue ; } BYTE nt = (BYTE)ps[i+1] ; if ( bt == '/' && nt == '/' ) { CString wstr = "<span class=\"lc\">//" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; i += 2 ; BYTE* bp = SearchTextSimple( (BYTE*)(&ps[i]) , slen-i , "\r", TRUE , TRUE ) ; if ( bp == NULL ) { memcpy( pd+j , (BYTE*)(&ps[i]) , slen-i ) ; j += slen-i ; CString wstr = "</span>" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; break ; } else { int wlen = bp - (BYTE*)(&ps[i]) ; memcpy( pd+j , (BYTE*)(&ps[i]) , wlen ) ; j += wlen ; CString wstr = "</span>" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; i += wlen ; } } else if ( bt == '/' && nt == '*' ) { CString wstr = "<span class=\"mc\">/*" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; i += 2 ; BYTE* bp = SearchTextSimple( (BYTE*)&ps[i] , slen-i , "*/", TRUE , TRUE ) ; if ( bp == NULL ) { memcpy( pd+j , &ps[i] , slen-i ) ; j += slen-i ; CString wstr = "</span>" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; break ; } else { int wlen = bp - (BYTE*)(&ps[i]) ; memcpy( pd+j , (const char*)(&ps[i]) , wlen+2 ) ; j += wlen+2 ; CString wstr = "</span>" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; i += wlen + 2 ; } } else if ( i == 0 || bt == ' ' || bt == '(' || bt == '\t' || bt == '\n' ) { if ( i != 0 ) pd[j++] = ps[i++] ; int klen = IsKeyword( &ps[i] , slen-i ) ; if ( klen == 0 ) continue ; CString wstr = "<span class=\"kw\">" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; memcpy( pd+j , (const char*)(&ps[i]) , klen ) ; j += klen ; i += klen ; wstr = "</span>" ; strcpy( pd+j , (const char*)wstr ) ; j += wstr.GetLength( ) ; } else { pd[j++] = ps[i++] ; } } return j ; } //***************************************************************************** // 機能 : 指定範囲の中で文字列を検索する。 // 戻り値: 見つかった文字列位置へのポインタ、NULLのときは見つからなかったことを意味する。 //***************************************************************************** BYTE* SearchTextSimple( BYTE* hStartP , int blen , LPCSTR lpszFind, BOOL bNext, BOOL bCase ) { int ret ; BYTE* hpszFound ; hpszFound = NULL ; UINT nLenSearch = lstrlen(lpszFind); ASSERT( nLenSearch > 0 ) ; // 0 だと != NULLで戻ってしまう?!!! int nChFind ; if ( _ismbblead( (BYTE)(*lpszFind) ) ) nChFind = 2 ; else nChFind = 1 ; BYTE* hStopP = hStartP + blen - nLenSearch + 1 ; if ( hStartP >= hStopP || blen < nChFind ) return NULL ; BYTE* hpsz = hStartP ; BYTE* hpszStop = hStopP ; for ( ; hpsz < hpszStop ; ) { if ( bCase ) ret = memcmp( (BYTE*)hpsz , lpszFind , nChFind ) ; else ret = _mbsnbicmp( (const BYTE*)hpsz , (const BYTE*)lpszFind , nChFind ) ; if ( ret == 0 ) { if ( bCase ) ret = memcmp( (BYTE*)hpsz , lpszFind , nLenSearch ) ; else ret = _mbsnbicmp( (const BYTE*)hpsz , (const BYTE*)lpszFind , nLenSearch ) ; if ( ret == 0 ) { hpszFound = hpsz ; if ( bNext ) break ; } } if ( _ismbblead( (BYTE)(*hpsz) ) ) hpsz += 2 ; else hpsz += 1 ; } return hpszFound ; } //***************************************************************************** // 機能 : //***************************************************************************** int IsKeyword( const char* pb , int slen ) { int kcount = sizeof(cppktbl)/sizeof(struct ccppkeywordtblstruct) ; int klen = 0 ; int i ; for ( i = 0 ; i < kcount ; i++ ) { klen = cppktbl[i].len ; if ( klen > slen ) continue ; if ( strncmp( pb , (const char*)cppktbl[i].str , klen ) == 0 ) break ; } if ( i == kcount ) return 0 ; if ( klen == slen ) return klen ; BYTE bt = (BYTE)pb[klen] ; if ( bt == ' ' || bt == ')' || bt == '*' ) return klen ; CString fstr = (const char*)(cppktbl[i].str) ; if ( bt == ':' && ( fstr == "private" || fstr == "protected" || fstr == "public" ) ) return klen ; return FALSE ; } //***************************************************************************** // SrcToHtmlPre.cpp : Ver1.00 2006/12/29 // Example : // /* void CMainFrame::OnDropFiles(HDROP hDropInfo) { // TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 // CMDIFrameWnd::OnDropFiles(hDropInfo); SetActiveWindow(); // activate us first ! UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0); nFiles = 1 ; CString path = "" ; TCHAR szFileName[_MAX_PATH]; for (UINT iFile = 0; iFile < nFiles; iFile++) { ::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH); path = (const char*)szFileName ; } ::DragFinish(hDropInfo); CString mstr = path ; mstr += "\n を変換しますが、よろしいですか?" ; if ( AfxMessageBox( (const char*)mstr , MB_OKCANCEL ) != IDOK ) return ; int dlen ; BYTE* ps = W_ReadTheFileEx( (const char*)path , 1024*1024*20 , (DWORD*)&dlen ) ; if ( ps == NULL ) return ; CString ostr = MakeStr( ps , dlen ) ; delete ps ; int result ; CString findstr = "<" ; CString newstr = "<" ; CString tstr = ReplaceStrUniFast( ostr , findstr , newstr , &result ) ; findstr = ">" ; newstr = ">" ; tstr = ReplaceStrUniFast( tstr , findstr , newstr , &result ) ; BYTE* pd = W_GetUserBuf( dlen * 3 + 20*1024 ) ; int nlen = SrcToHtmlPre( (const char*)tstr , (char*)pd , tstr.GetLength( ) ) ; if ( nlen <= 0 || nlen > 1024*1024*40 ) { delete pd ; return ; } ostr = "<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n<title></title>\r\n<link href=\"sstyle.css\" rel=\"stylesheet\" type=\"text/css\">\r\n</head>\r\n\r\n<body>\r\n<pre>\r\n" ; tstr = MakeStr( pd , nlen ) ; ostr += tstr ; ostr += "</pre>\r\n</body>\r\n</html>" ; CString fname = GetFileTitlePart( path ) ; CString outpath = "D:\\HomePage\\src\\" ; outpath += fname ; outpath += ".html" ; W_WriteTheFile( (const char*)outpath , (BYTE*)(const char*)ostr , ostr.GetLength( ) ) ; delete pd ; } */ // 補足 : // W_ReadTheFileEx, MakeStr, GetFileTitlePart, W_WriteTheFile, W_GetUserBuf, ReplaceStrUniFast は、 // ローカルな関数です。 // InitInstanceで pMainFrame->DragAcceptFiles(); でDropも有効にしておくこと。 // 元のソースファイルのタブは、エディタで空白に変換しておくこと(さもないと、ブラウザ表示でずれる) // // sstyle.cssファイルの内容例 --- 上の例では、D:\HomePage\src に置いておく必要があります。 // .lc { color: green; } // .mc { color: green; } // .kw { color: blue; } // // Copyright(C) Edcom Inc. (http://www.edcom.jp/) All rights reserved. //*****************************************************************************