说起来有点不好意思,也就是上一篇博客的时候用了下Markdown,结果发现这种方式写博客比较轻松。对于我这样的,能编点应用程序,但对网页技术只是了解点皮毛,远谈不上精通的人来说,Markdown比较有用。
毕竟自己看点东西也希望规范一些,网页效果很好,但技术门派太多,也一直没心思去深入研究学习。
有了一篇博客的基础,突然想把自己程序的日志采用Markdown来改造一下。
每次写Markdown文件需要有个目标,用流方式来实现即可。第一次就创建,后续直接打开续写。
TFileStream * __fastcall TDrLUA::GetLogStream() {
TFileStream * ErrorsLog = NULL;
UnicodeString LogFile = FStatusXmlFileName;
try {
if (FileExists(LogFile)) {
ErrorsLog = new TFileStream(LogFile, fmOpenReadWrite | fmShareExclusive);
ErrorsLog->Position = ErrorsLog->Size;
}
else {
ErrorsLog = new TFileStream(LogFile, fmCreate);
AnsiString info = THelper::FormatString(L"# 脚本日志报告\n- 程序当前版本:%s\n- 程序修改时刻:%s\n",
TGraphApp::AppVersion, THelper::File::GetFileTimeDesc(Application->ExeName, cftLastWrite));
ErrorsLog->Write((void*)(info.c_str()), info.Length());
}
}
catch (...) {
ErrorsLog = NULL;
}
return ErrorsLog;
}
这样,后续操作只需要直接操作GetLogStream返回流对象
准备将信息展现为表格形式,第一列为时刻,第二列为信息。所以加一个小的控制,FStartLogTextFlag
void __fastcall TDrLUA::LogScript_Text(UnicodeString text) {
TFileStream * fs = GetLogStream();
if(fs) {
UnicodeString logInfo = text;
if(!FStartLogTextFlag) {
logInfo = THelper::FormatString(L"|时刻|信息|\n|:--|:--|\n|%s|%s|\n",
TTypeConvert::Moment2String(GetTickCount(), L"hh:nn:ss:zzz"),
logInfo);
} else
logInfo = THelper::FormatString(L"|%s|%s|\n",
TTypeConvert::Moment2String(GetTickCount(), L"hh:nn:ss:zzz"),
logInfo);
AnsiString info = logInfo;
fs->Write((void*)(info.c_str()), info.Length());
FStartLogTextFlag = true;
}
delete fs;
}
}
当然,信息的展现形式,如字体颜色之类的,在调用时按需处理
日志信息就象是流水账,加上标题就更为脉络清晰一些。直接就加个#即可。目前先只处理一级标题,如果需要多级标题,加一个参数int level应该就足够
void __fastcall TDrLUA::LogScript_Title(UnicodeString text) {
TFileStream * fs = GetLogStream();
if(fs) {
AnsiString info = THelper::FormatString(L"\n---\n# %s\n", text);
fs->Write((void*)(info.c_str()), info.Length());
FStartLogTextFlag = false;
delete fs;
}
}
发现需要加上font color=#…才能控制颜色,这个在输出的时候加上即可。
LogScript_Text(THelper::FormatString(L"&font color=%s;**%s**&font;",
TTypeConvert::WebColorString(color), info), 0);
按Markdown图片格式进入输出
void __fastcall TDrLUA::LogScript_Mat(cv::Mat& mat) {
UnicodeString destPicFileName = THelper::FormatString(L"%s%s.png",
ExtractFilePath(FStatusXmlFileName), TTypeConvert::Moment2String(GetTickCount(), L"hh_nn_ss_zzz"));
CvHelper::MatToFile(mat, destPicFileName);
LogScript_Text(THelper::FormatString(L"&font color=#ff0000;**![警告:返回了空图片](%s \"返回图片\")**&font;", ExtractFileName(destPicFileName)), 0);
}
在网上搜了一下,直接用shutdown这个JS模块处理。下载到固定文件夹。设计一个样本报告网页文件
<!DOCTYPE html>
<html><head>
<title>&Title;</title>
<script type="text/javascript" src="&AppPath;Res\showdown\showdown.js"></script>
</head><body><div id="result"></div>
<script type="text/javascript">
function convert(){
var text = "&MarkDownContent;";
var converter = new showdown.Converter();
var html = converter.makeHtml(text);
document.getElementById("result").innerHTML = html;
}
window.onload=function(){convert(); }
</script></body>
在程序生成的时候,相应替换上面文件中&…;即可
UnicodeString __fastcall THelper::Log::BuildMarkDownReport(UnicodeString markDownFileName, UnicodeString destTitle) {
UnicodeString templateFileName = THelper::File::GetPath_Application() + L"res\\showdown\\report.html";
UnicodeString destHtmlFileName = ChangeFileExt(markDownFileName, L".html");
if(FileExists(destHtmlFileName))
DeleteFile(destHtmlFileName);
if(FileExists(templateFileName)) {
TStrings * lines = new TStringList;
lines->LoadFromFile(templateFileName, System::Sysutils::TEncoding::UTF8);
UnicodeString markDownContent = THelper::File::GetFileContent(markDownFileName, false);
if(markDownContent.Length() == 0)
markDownContent = THelper::FormatString(L"#文件 '%s' 无内容", ExtractFileName(markDownFileName));
for(int i = 0; i < lines->Count; ++i) {
UnicodeString content = lines->Strings[i];
if(content.Pos(L"&AppPath;"))
THelper::String::ReplaceStringInStr(content, L"&AppPath;", THelper::File::GetPath_Application());
else if(content.Pos(L"&MarkDownContent;"))
THelper::String::ReplaceStringInStr(content, L"&MarkDownContent;", markDownContent);
else if(content.Pos(L"&Title;"))
THelper::String::ReplaceStringInStr(content, L"&Title;", destTitle);
else continue;
lines->Strings[i] = content;
}
lines->SaveToFile(destHtmlFileName, System::Sysutils::TEncoding::UTF8);
delete lines;
}
return destHtmlFileName;
}
直接用CEF3浏览器显示。