/* * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "synhtmlexporter.h" #include "../MiscProcs.h" #include SynHTMLExporter::SynHTMLExporter(int tabSize) { mClipboardFormat = "text/html"; mDefaultFilter = "HTML Documents (*.htm;*.html)|*.htm;*.html"; // setup array of chars to be replaced mReplaceReserved['&'] = "&"; mReplaceReserved['<'] = "<"; mReplaceReserved['>'] = ">"; mReplaceReserved['"'] = """; mReplaceReserved[' '] = " "; mReplaceReserved['\t'] = mReplaceReserved[' '].repeated(tabSize); mCreateHTMLFragment = false; } bool SynHTMLExporter::createHTMLFragment() const { return mCreateHTMLFragment; } void SynHTMLExporter::setCreateHTMLFragment(bool createHTMLFragment) { mCreateHTMLFragment = createHTMLFragment; } QString SynHTMLExporter::AttriToCSS(PSynHighlighterAttribute Attri, const QString &UniqueAttriName) { QString StyleName = MakeValidName(UniqueAttriName); QString Result = "." + StyleName + " { "; if (mUseBackground && Attri->background().isValid()) Result += "background-color: " + ColorToHTML(Attri->background()) + "; "; if (Attri->foreground().isValid()) Result += "color: " + ColorToHTML(Attri->foreground()) + "; "; if (Attri->styles().testFlag(SynFontStyle::fsBold)) Result += "font-weight: bold; "; if (Attri->styles().testFlag(SynFontStyle::fsItalic)) Result += "font-style: italic; "; if (Attri->styles().testFlag(SynFontStyle::fsUnderline)) Result += "text-decoration: underline; "; if (Attri->styles().testFlag(SynFontStyle::fsStrikeOut)) Result += "text-decoration: line-through; "; Result += "}"; return Result; } bool SynHTMLExporter::AttriToCSSCallback(PSynHighlighter , PSynHighlighterAttribute Attri, const QString& UniqueAttriName, QList params) { QString& styles = *static_cast(params[0]); styles.append(AttriToCSS(Attri,UniqueAttriName) + lineBreak()); return true; } QString SynHTMLExporter::ColorToHTML(const QColor &AColor) { return AColor.name(); } QString SynHTMLExporter::GetStyleName(PSynHighlighter Highlighter, PSynHighlighterAttribute Attri) { QString result; EnumHighlighterAttris(Highlighter,false, std::bind( &SynHTMLExporter::StyleNameCallback,this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), {&Attri,&result}); return result; } QString SynHTMLExporter::MakeValidName(const QString &Name) { QString Result; for (QChar ch:Name) { ch = ch.toLower(); if (ch == '.' || ch =='_') Result += '-'; else if ((ch >='a' && ch <= 'z') || (ch>='0' && ch<='9') || (ch == '-')) Result += ch; } return Result; } bool SynHTMLExporter::StyleNameCallback(PSynHighlighter /*Highlighter*/, PSynHighlighterAttribute Attri, const QString& UniqueAttriName, QList params) { PSynHighlighterAttribute& AttriToFind = *static_cast(params[0]); QString& StyleName = *static_cast(params[1]); if (Attri == AttriToFind) { StyleName.clear(); StyleName.append(MakeValidName(UniqueAttriName)); return false; } return true; } void SynHTMLExporter::FormatAttributeDone(bool , bool , SynFontStyles ) { AddData(""); } void SynHTMLExporter::FormatAttributeInit(bool , bool , SynFontStyles ) { QString StyleName = GetStyleName(mHighlighter, mLastAttri); AddData(QString("").arg(StyleName)); } void SynHTMLExporter::FormatAfterLastAttribute() { AddData(""); } void SynHTMLExporter::FormatBeforeFirstAttribute(bool, bool, SynFontStyles) { QString StyleName = GetStyleName(mHighlighter, mLastAttri); AddData(QString("").arg(StyleName)); } void SynHTMLExporter::FormatNewLine() { AddData("
"); AddNewLine(); } QString SynHTMLExporter::GetFooter() { QString Result = ""; Result = "
" + lineBreak(); if (mCreateHTMLFragment) Result += ""; Result += ""+lineBreak()+ ""; return Result; } QString SynHTMLExporter::GetFormatName() { return "HTML"; } QString SynHTMLExporter::GetHeader() { using namespace std::placeholders; QString Styles; EnumHighlighterAttris(mHighlighter, true, std::bind(&SynHTMLExporter::AttriToCSSCallback, this, _1, _2, _3, _4), {&Styles}); QString HTMLAsTextHeader = ""+lineBreak() + "" + lineBreak() + "" + lineBreak() + ""+ lineBreak() + "%1" + lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak(); QString Header = HTMLAsTextHeader .arg(mTitle) .arg(QString(mCharset)) .arg(ColorToHTML(mForegroundColor)) .arg(ColorToHTML(mBackgroundColor)) .arg(Styles); if (mCreateHTMLFragment) { HTMLAsTextHeader = ""+lineBreak() + "" + lineBreak() + "" + lineBreak() + ""+ lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak() + "" + lineBreak(); Header = HTMLAsTextHeader .arg(QString(mCharset)) .arg(ColorToHTML(mForegroundColor)) .arg(ColorToHTML(mBackgroundColor)) .arg(Styles); } QString Result = Header; if (mCreateHTMLFragment) { Result += ""; } Result += QString("") .arg(pixelToPoint(mFont.pixelSize())) .arg(mFont.family()); return Result; } void SynHTMLExporter::SetTokenAttribute(PSynHighlighterAttribute Attri) { mLastAttri = Attri; SynExporter::SetTokenAttribute(Attri); }