www.pudn.com > TidyWin32-src.zip > TidyProxy.cpp
#include "StdAfx.h" #include// for _open() and _filelength() #include #include "TidyProxy.h" #include "Profile.h" // Define static member variables list CTidyProxy::m_tidy_out_msgs; string CTidyProxy::m_tidy_out_msg_line; string CTidyProxy::m_outc_string; string CTidyProxy::m_TidyDefinedEmptyTags, CTidyProxy::m_TidyDefinedInlineTags, CTidyProxy::m_TidyDefinedBlockTags, CTidyProxy::m_TidyDefinedPreTags; FILE* CTidyProxy::m_fpErrFile = NULL; const char* CTidyProxy::TIDY_YES = "yes"; const char* CTidyProxy::TIDY_NO = "no"; //------------------------------------------------------------------- CTidyProxy::CTidyProxy(bool bEnableAllOptions) : m_bEnableAllOptions(bEnableAllOptions) { CTidyProxy::writeback = tidy::no; CTidyProxy::KeepFileTimes = tidy::yes; CTidyProxy::Emacs = tidy::no; Set_tidy_out_Callback(CTidyProxy::tidy_out_Callback); Set_outc_Callback(CTidyProxy::outc_Callback); Set_defNewTag_Callback(CTidyProxy::defNewTag_Callback); } //------------------------------------------------------------------- void CTidyProxy::Reset() { m_tidy_out_msgs.clear(); m_tidy_out_msg_line.erase(); m_outc_string.erase(); tidy::totalerrors = tidy::totalwarnings = tidy::optionerrors = 0; } void CTidyProxy::DoTidy(const char* sourceFileName, const char* destFileName) { DefineNewTags(NewEmptyTags, m_NewEmptyTags); DefineNewTags(NewInlineTags, m_NewInlineTags); DefineNewTags(NewBlockTags, m_NewBlockTags); DefineNewTags(NewPreTags, m_NewPreTags); if (m_bEnableAllOptions) { tidy::KeepFileTimes = CTidyProxy::KeepFileTimes; tidy::Emacs = CTidyProxy::Emacs; if (errfile.length() > 0) m_fpErrFile = fopen(errfile.c_str(), "wt"); } // reserve space for m_outc_string, for performance int fh = _open(sourceFileName, _O_RDONLY); if (fh != -1) { long len = _filelength(fh); len += len / 2; m_outc_string.reserve(len); _close(fh); } int argc = 2; char* argv[] = { "tidy", const_cast (sourceFileName) }; tidy_main(argc, argv, destFileName); if (m_fpErrFile) { fclose(m_fpErrFile); m_fpErrFile = NULL; } } void CTidyProxy::AdjustConfig() { tidy::AdjustConfig(); // Word 2000 needs o:p to be declared inline if (tidy::Word2000 == tidy::yes) { list tagList = ParseTags(m_NewInlineTags); if (find(tagList.begin(), tagList.end(), "o:p") == tagList.end() && find(tagList.begin(), tagList.end(), "O:P") == tagList.end()) { if (m_NewInlineTags.length() > 0) m_NewInlineTags.append(" "); m_NewInlineTags.append("o:p"); } } } const char* CTidyProxy::BoolToStr(const tidy::Bool b) { if (b == tidy::yes) return TIDY_YES; else return TIDY_NO; } CTidyProxy::ConfigListT CTidyProxy::BuildConfigList() { using namespace tidy; ConfigListT confList; char tmpStr[128]; // The 'indent' property should be set early in the config file if (GetIndent() != Log3_False) { string val; if (GetIndent() == Log3_True) val = "yes"; else val = "auto"; confList.push_back(SettingPair("indent", val)); } if (tidy::spaces != 2) { sprintf(tmpStr, "%d", tidy::spaces); confList.push_back(SettingPair("indent-spaces", tmpStr)); } if (m_NewEmptyTags.length() > 0) confList.push_back(SettingPair("new-empty-tags", m_NewEmptyTags)); if (m_NewInlineTags.length() > 0) confList.push_back(SettingPair("new-inline-tags", m_NewInlineTags)); if (m_NewBlockTags.length() > 0) confList.push_back(SettingPair("new-blocklevel-tags", m_NewBlockTags)); if (m_NewPreTags.length() > 0) confList.push_back(SettingPair("new-pre-tags", m_NewPreTags)); if (CTidyProxy::errfile.length() > 0) confList.push_back(SettingPair("error-file", CTidyProxy::errfile)); if (tidy::wraplen != 68) { sprintf(tmpStr, "%d", tidy::wraplen); confList.push_back(SettingPair("wrap", tmpStr)); } if (tidy::CharEncoding != ASCII) { string val; switch (tidy::CharEncoding) { case RAW: val = "raw"; break; case LATIN1: val = "latin1"; break; case UTF8: val = "utf8"; break; case ISO2022: val = "iso2022"; break; case MACROMAN: val = "mac"; break; } confList.push_back(SettingPair("char-encoding", val)); } if (tidy::tabsize != 4) { sprintf(tmpStr, "%d", tidy::tabsize); confList.push_back(SettingPair("tab-size", tmpStr)); } if (doctype_mode != doctype_auto) { string val; switch (doctype_mode) { case doctype_omit: val = "omit"; break; case doctype_strict: val = "strict"; break; case doctype_loose: val = "loose"; break; case doctype_user: val = doctype_str; break; } confList.push_back(SettingPair("doctype", val)); } if (alt_text) confList.push_back(SettingPair("alt-text", alt_text)); // Booleans if (tidy::TidyMark != yes) confList.push_back(SettingPair("tidy-mark", BoolToStr(tidy::TidyMark))); if (tidy::HideEndTags != no) confList.push_back(SettingPair("hide-endtags", BoolToStr(tidy::HideEndTags))); if (tidy::EncloseBodyText != no) confList.push_back(SettingPair("enclose-text", BoolToStr(tidy::EncloseBodyText))); if (tidy::EncloseBlockText != no) confList.push_back(SettingPair("enclose-block-text", BoolToStr(tidy::EncloseBlockText))); if (tidy::MakeClean != no) confList.push_back(SettingPair("clean", BoolToStr(tidy::MakeClean))); if (tidy::DropFontTags != no) confList.push_back(SettingPair("drop-font-tags", BoolToStr(tidy::DropFontTags))); if (tidy::LogicalEmphasis != no) confList.push_back(SettingPair("logical-emphasis", BoolToStr(tidy::LogicalEmphasis))); if (tidy::DropEmptyParas != yes) confList.push_back(SettingPair("drop-empty-paras", BoolToStr(tidy::DropEmptyParas))); if (tidy::Word2000 != no) confList.push_back(SettingPair("word-2000", BoolToStr(tidy::Word2000))); if (tidy::FixComments != yes) confList.push_back(SettingPair("fix-bad-comments", BoolToStr(tidy::FixComments))); if (tidy::FixBackslash != yes) confList.push_back(SettingPair("fix-backslash", BoolToStr(tidy::FixBackslash))); if (tidy::XmlTags != no) confList.push_back(SettingPair("input-xml", BoolToStr(tidy::XmlTags))); if (tidy::XmlOut != no) confList.push_back(SettingPair("output-xml", BoolToStr(tidy::XmlOut))); if (tidy::xHTML != no) confList.push_back(SettingPair("output-xhtml", BoolToStr(tidy::xHTML))); if (tidy::XmlPi != no) confList.push_back(SettingPair("add-xml-decl", BoolToStr(tidy::XmlPi))); if (tidy::XmlPIs != no) confList.push_back(SettingPair("assume-xml-procins", BoolToStr(tidy::XmlPIs))); if (tidy::XmlSpace != no) confList.push_back(SettingPair("add-xml-space", BoolToStr(tidy::XmlSpace))); if (tidy::NumEntities != no) confList.push_back(SettingPair("numeric-entities", BoolToStr(tidy::NumEntities))); if (tidy::QuoteMarks != no) confList.push_back(SettingPair("quote-marks", BoolToStr(tidy::QuoteMarks))); if (tidy::QuoteNbsp != yes) confList.push_back(SettingPair("quote-nbsp", BoolToStr(tidy::QuoteNbsp))); if (tidy::QuoteAmpersand != yes) confList.push_back(SettingPair("quote-ampersand", BoolToStr(tidy::QuoteAmpersand))); if (tidy::IndentAttributes != no) confList.push_back(SettingPair("indent-attributes", BoolToStr(tidy::IndentAttributes))); if (tidy::WrapAttVals != no) confList.push_back(SettingPair("wrap-attributes", BoolToStr(tidy::WrapAttVals))); if (tidy::WrapScriptlets != no) confList.push_back(SettingPair("wrap-script-literals", BoolToStr(tidy::WrapScriptlets))); if (tidy::WrapAsp != yes) confList.push_back(SettingPair("wrap-asp", BoolToStr(tidy::WrapAsp))); if (tidy::WrapJste != yes) confList.push_back(SettingPair("wrap-jste", BoolToStr(tidy::WrapJste))); if (tidy::WrapPhp != yes) confList.push_back(SettingPair("wrap-php", BoolToStr(tidy::WrapPhp))); if (tidy::BreakBeforeBR != no) confList.push_back(SettingPair("break-before-br", BoolToStr(tidy::BreakBeforeBR))); if (tidy::UpperCaseTags != no) confList.push_back(SettingPair("uppercase-tags", BoolToStr(tidy::UpperCaseTags))); if (tidy::UpperCaseAttrs != no) confList.push_back(SettingPair("uppercase-attributes", BoolToStr(tidy::UpperCaseAttrs))); if (tidy::OnlyErrors != no) confList.push_back(SettingPair("markup", BoolToStr(tidy::OnlyErrors == yes ? no : yes))); if (tidy::Quiet != no) confList.push_back(SettingPair("quiet", BoolToStr(tidy::Quiet))); if (tidy::ShowWarnings != yes) confList.push_back(SettingPair("show-warnings", BoolToStr(tidy::ShowWarnings))); if (tidy::BurstSlides != no) confList.push_back(SettingPair("split", BoolToStr(tidy::BurstSlides))); if (CTidyProxy::writeback != no) confList.push_back(SettingPair("write-back", BoolToStr(CTidyProxy::writeback))); if (CTidyProxy::KeepFileTimes != yes) confList.push_back(SettingPair("keep-time", BoolToStr(CTidyProxy::KeepFileTimes))); if (CTidyProxy::Emacs != no) confList.push_back(SettingPair("gnu-emacs", BoolToStr(CTidyProxy::Emacs))); if (tidy::LiteralAttribs != no) confList.push_back(SettingPair("literal-attributes", BoolToStr(tidy::LiteralAttribs))); return confList; } void CTidyProxy::LoadConfig(const char* fileName) { ResetConfig(); tidy::InitTidy(); tidy::ParseConfigFile(const_cast (fileName)); AdjustConfig(); tidy::DeInitTidy(); m_NewEmptyTags = m_TidyDefinedEmptyTags; m_TidyDefinedEmptyTags.erase(); m_NewInlineTags = m_TidyDefinedInlineTags; m_TidyDefinedInlineTags.erase(); m_NewBlockTags = m_TidyDefinedBlockTags; m_TidyDefinedBlockTags.erase(); m_NewPreTags = m_TidyDefinedPreTags; m_TidyDefinedPreTags.erase(); if (tidy::errfile) { CTidyProxy::errfile = tidy::errfile; tidy::MemFree(tidy::errfile); tidy::errfile = 0; } CTidyProxy::writeback = tidy::writeback; tidy::writeback = tidy::no; CTidyProxy::KeepFileTimes = tidy::KeepFileTimes; CTidyProxy::Emacs = tidy::Emacs; } void CTidyProxy::SaveConfig(ostream& os) { os << "// HTML Tidy configuration file created by TidyGUI" << endl; ConfigListT configList = BuildConfigList(); if (configList.empty()) os << "// All settings have their default value" << endl; for (ConfigListT::const_iterator it = configList.begin(); it != configList.end(); ++it) { os << it->first << ": " << it->second << endl; } } void CTidyProxy::CopyConfig() { OpenClipboard(NULL); EmptyClipboard(); ConfigListT configList = BuildConfigList(); string str; for (ConfigListT::const_iterator it = configList.begin(); it != configList.end(); ++it) { str.append("--"); str.append(it->first); str.append(" "); str.append(it->second); str.append(" "); } int len = str.length(); if (len) { HGLOBAL h = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, len); if (h == NULL) { CloseClipboard(); return; } LPTSTR lptstrCopy = (LPTSTR)GlobalLock(h); strcpy(lptstrCopy, str.c_str()); GlobalUnlock(h); SetClipboardData(CF_TEXT, h); } CloseClipboard(); } void CTidyProxy::ResetConfig() { using namespace tidy; m_NewEmptyTags = m_NewInlineTags = m_NewBlockTags = m_NewPreTags = ""; CTidyProxy::errfile = ""; spaces = 2; wraplen = 68; tidy::CharEncoding = ASCII; tabsize = 4; doctype_mode = doctype_auto; if (doctype_str) { MemFree(doctype_str); doctype_str = 0; } if (alt_text) { MemFree(alt_text); alt_text = 0; } if (slide_style) { MemFree(slide_style); slide_style = 0; } IndentContent = no; SmartIndent = no; TidyMark = yes; HideEndTags = no; EncloseBodyText = no; EncloseBlockText = no; MakeClean = no; DropFontTags = no; LogicalEmphasis = no; DropEmptyParas = yes; Word2000 = no; FixComments = yes; FixBackslash = yes; XmlTags = no; XmlOut = no; xHTML = no; XmlPi = no; XmlPIs = no; XmlSpace = no; NumEntities = no; QuoteMarks = no; QuoteNbsp = yes; QuoteAmpersand = yes; IndentAttributes = no; WrapAttVals = no; WrapScriptlets = no; WrapAsp = yes; WrapJste = yes; WrapPhp = yes; BreakBeforeBR = no; UpperCaseTags = no; UpperCaseAttrs = no; OnlyErrors = no; Quiet = no; ShowWarnings = yes; BurstSlides = no; CTidyProxy::writeback = no; CTidyProxy::KeepFileTimes = yes; CTidyProxy::Emacs = no; LiteralAttribs = no; } //------------------------------------------------------------------- unsigned int CTidyProxy::GetTotalErrors() const { return tidy::totalerrors; } unsigned int CTidyProxy::GetTotalWarnings() const { return tidy::totalwarnings; } unsigned int CTidyProxy::GetOptionErrors() const { return tidy::optionerrors; } //------------------------------------------------------------------- string CTidyProxy::GetDocType() const { switch(tidy::doctype_mode) { case tidy::doctype_omit: return "omit"; case tidy::doctype_auto: return "auto"; case tidy::doctype_strict: return "strict"; case tidy::doctype_loose: return "loose"; case tidy::doctype_user: if (tidy::doctype_str) return tidy::doctype_str; default: return ""; } } void CTidyProxy::SetDocType(const char* str) { if (stricmp(str, "omit") == 0) tidy::doctype_mode = tidy::doctype_omit; else if (stricmp(str, "auto") == 0 || strlen(str) == 0) tidy::doctype_mode = tidy::doctype_auto; else if (stricmp(str, "strict") == 0) tidy::doctype_mode = tidy::doctype_strict; else if (stricmp(str, "loose") == 0) tidy::doctype_mode = tidy::doctype_loose; else { tidy::doctype_mode = tidy::doctype_user; if (tidy::doctype_str) tidy::MemFree(tidy::doctype_str); tidy::doctype_str = tidy::wstrdup(const_cast (str)); } } //------------------------------------------------------------------- void CTidyProxy::SetNewTags(NewTagsTag tagsType, const char* tagStr) { // Cache new tag strings switch (tagsType) { case NewEmptyTags: m_NewEmptyTags = tagStr; break; case NewInlineTags: m_NewInlineTags = tagStr; break; case NewBlockTags: m_NewBlockTags = tagStr; break; case NewPreTags: m_NewPreTags = tagStr; break; } } list CTidyProxy::ParseTags(const string& tagStr) { list tagList; string seps = " \t,"; string::size_type startPos = tagStr.find_first_not_of(seps); while (startPos != string::npos) { string::size_type endPos = tagStr.find_first_of(seps, startPos); string oneTag = tagStr.substr(startPos, endPos - startPos); startPos = tagStr.find_first_not_of(seps, endPos); ATLTRACE("TAG: %s\n", oneTag.c_str()); tagList.push_back(oneTag); } return tagList; } void CTidyProxy::DefineNewTags(NewTagsTag tagsType, const string& tagStr) { list tagList = ParseTags(tagStr); for (list ::const_iterator it = tagList.begin(); it != tagList.end(); ++it) { const char* oneTag = it->c_str(); switch (tagsType) { case NewEmptyTags: tidy::DefineEmptyTag(const_cast (oneTag)); break; case NewInlineTags: tidy::DefineInlineTag(const_cast (oneTag)); break; case NewBlockTags: tidy::DefineBlockTag(const_cast (oneTag)); break; case NewPreTags: tidy::DefinePreTag(const_cast (oneTag)); break; } } } const string& CTidyProxy::GetNewTags(NewTagsTag tagsType) { switch (tagsType) { case NewEmptyTags: return m_NewEmptyTags; case NewInlineTags: return m_NewInlineTags; case NewBlockTags: return m_NewBlockTags; case NewPreTags: return m_NewPreTags; default: // shouldn't happen, but makes the compiler happy return m_NewEmptyTags; } } //------------------------------------------------------------------- string CTidyProxy::GetAltText() const { if (tidy::alt_text) return tidy::alt_text; else return ""; } void CTidyProxy::SetAltText(const char* str) { if (tidy::alt_text) { tidy::MemFree(tidy::alt_text); tidy::alt_text = 0; } string nonSpaceStr = str; if (nonSpaceStr.find_first_not_of(" \t") != string::npos) tidy::alt_text = tidy::wstrdup(const_cast (str)); } //------------------------------------------------------------------- void CTidyProxy::SetCharEncoding(CharEncoding enc) { switch (enc) { case Enc_Raw: tidy::CharEncoding = RAW; break; case Enc_ASCII: tidy::CharEncoding = ASCII; break; case Enc_Latin1: tidy::CharEncoding = LATIN1; break; case Enc_UTF8: tidy::CharEncoding = UTF8; break; case Enc_ISO2022: tidy::CharEncoding = ISO2022; break; case Enc_MacRoman: tidy::CharEncoding = MACROMAN; break; default: tidy::CharEncoding = LATIN1; } } CTidyProxy::CharEncoding CTidyProxy::GetCharEncoding() const { switch (tidy::CharEncoding) { case RAW: return Enc_Raw; break; case ASCII: return Enc_ASCII; break; case LATIN1: return Enc_Latin1; break; case UTF8: return Enc_UTF8; break; case ISO2022: return Enc_ISO2022; break; case MACROMAN: return Enc_MacRoman; break; default: return Enc_ASCII; } } //------------------------------------------------------------------- void CTidyProxy::SetIndent(CTidyProxy::Logical3 val) { // See tidy::ParseIndent switch (val) { case Log3_False: tidy::IndentContent = tidy::no; tidy::SmartIndent = tidy::no; break; case Log3_True: tidy::IndentContent = tidy::yes; tidy::SmartIndent = tidy::no; break; case Log3_Maybe: tidy::IndentContent = tidy::yes; tidy::SmartIndent = tidy::yes; break; } } CTidyProxy::Logical3 CTidyProxy::GetIndent() const { if (tidy::IndentContent == tidy::no) return Log3_False; if (tidy::SmartIndent == tidy::no) return Log3_True; return Log3_Maybe; } //------------------------------------------------------------------- //------------------------------------------------------------------- void CTidyProxy::tidy_out_Callback(FILE *fp, const char* msg) { // (fp should always be stderr) string smsg = msg; // remove any newline characters string::size_type pos; while ((pos = smsg.find('\n')) != string::npos) { smsg.erase(pos, pos + 1); } m_tidy_out_msg_line += smsg; if (msg[strlen(msg) - 1] == '\n') { m_tidy_out_msgs.push_back(m_tidy_out_msg_line); m_tidy_out_msg_line.erase(); } if (m_fpErrFile) { fputs(msg, m_fpErrFile); } } void CTidyProxy::outc_Callback(unsigned int c, FILE *fp) { if (fp != stdout) putc(c, fp); else { if (c == 0x0A) m_outc_string += '\r'; m_outc_string += c; } } void CTidyProxy::defNewTag_Callback(newTagT tagType, const char* newTag) { string* pTidyDefinedTags; switch (tagType) { case newInlineTag: pTidyDefinedTags = &m_TidyDefinedInlineTags; break; case newBlockTag: pTidyDefinedTags = &m_TidyDefinedBlockTags; break; case newEmptyTag: pTidyDefinedTags = &m_TidyDefinedEmptyTags; break; case newPreTag: pTidyDefinedTags = &m_TidyDefinedPreTags; break; } if (pTidyDefinedTags->length() > 0) pTidyDefinedTags->append(", "); pTidyDefinedTags->append(newTag); }