📄 copyeventhandler.cxx
字号:
// Copyright (c) 1995 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "config.h"#include "CopyEventHandler.h"#include "macros.h"#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endifinlineOutputCharStream &operator<<(OutputCharStream &os, const MarkupIter &iter){ return os.write(iter.charsPointer(), iter.charsLength());}#ifdef __GNUG__inline#endifBoolean CopyEventHandler::noOutput(){ if (inInstance_) { if (normalizeFlags_ & normalizeExpand) { if (entityLevel_ >= outputEntityLevel_) return 0; } else { if (entityLevel_ == outputEntityLevel_) return 0; } } else if (normalizeFlags_ & normalizeIncludeProlog) { if (normalizeFlags_ & normalizeExpandProlog) { if (entityLevel_ >= outputEntityLevel_) return 0; } else { if (entityLevel_ == outputEntityLevel_) return 0; } } return 1;}inlineBoolean CopyEventHandler::doNothing(Event *event){ if (noOutput()) { delete event; return 1; } else return 0;}inlinevoid CopyEventHandler::withNamedCharRef(const StringC &str, const Location &loc){ withNamedCharRef(str.data(), str.size(), loc);}staticvoid escape(OutputCharStream &s, Char c){ s << "&#" << (unsigned long)c << ";";}CopyEventHandler::CopyEventHandler(OutputCharStream *os, unsigned normalizeFlags, const StringC &outputEntity): os_(os), topOs_(os), inInstance_(0), entityLevel_(0), normalizeFlags_(normalizeFlags), outputEntity_(outputEntity), omittagHoist_(0), inSpecialMarkedSection_(0), currentAttributes_(0), emptyElementNormal_(0){ outputEntityLevel_ = outputEntity_.size() == 0 ? 0 : unsigned(-1); os_->setEscaper(escape);}CopyEventHandler::~CopyEventHandler(){ delete os_;}void CopyEventHandler::markup(const Location &loc, const Markup &markup){ if (!noOutput()) outputMarkup(loc, markup);}void CopyEventHandler::sgmlDecl(SgmlDeclEvent *event){ if (event->implySystemId().size() == 0 && !event->location().origin().isNull() && (normalizeFlags_ & normalizeIncludeProlog)) { syntax_ = event->refSyntaxPointer(); sd_ = event->refSdPointer(); outputMarkup(event->location(), event->markup()); } syntax_ = event->prologSyntaxPointer(); instanceSyntax_ = event->instanceSyntaxPointer(); if (instanceSyntax_->namecaseGeneral()) instanceSyntax_->generalSubstTable()->inverseTable(lowerSubst_); else if (instanceSyntax_->namecaseEntity()) instanceSyntax_->entitySubstTable()->inverseTable(lowerSubst_); sd_ = event->sdPointer(); emptyElementNormal_ = sd_->emptyElementNormal(); delete event;}void CopyEventHandler::endProlog(EndPrologEvent *event){ inInstance_ = 1; syntax_ = instanceSyntax_; delete event;}void CopyEventHandler::data(DataEvent *event){ omittagHoist_ = 0; if (doNothing(event)) return; if (event->entity()) entityRef(event->location().origin()->asEntityOrigin()); else { size_t n = event->dataLength(); unsigned long dummy; if (n > 1 || !event->isRe(dummy)) writeData(event->data(), n, event->location()); } delete event;}void CopyEventHandler::nonSgmlChar(NonSgmlCharEvent *event){ omittagHoist_ = 0; if (doNothing(event)) return; Char c = event->character(); writeData(&c, 1, event->location()); delete event;}void CopyEventHandler::writeData(const Char *p, size_t n, const Location &loc){ const Markup *markupPtr; if (n == 1 && loc.origin()->isNumericCharRef(markupPtr)) { if (markupPtr) outputMarkup(loc.origin()->parent(), *markupPtr); } else withNamedCharRef(p, n, loc);}void CopyEventHandler::withNamedCharRef(const Char *p, size_t n, const Location &loc){ if (n > 0) { const Origin *origin = loc.origin().pointer(); if (origin) { NamedCharRef ref; if (origin->isNamedCharRef(loc.index(), ref)) { Markup markup; markup.addDelim(Syntax::dCRO); markup.addName(ref.origName().data(), ref.origName().size()); switch (ref.refEndType()) { case NamedCharRef::endOmitted: break; case NamedCharRef::endRE: markup.addRefEndRe(); break; case NamedCharRef::endRefc: markup.addDelim(Syntax::dREFC); break; } outputMarkup(Location(loc.origin(), ref.refStartIndex()), markup); p++; n--; } } } os().write(p, n);}void CopyEventHandler::reOrigin(ReOriginEvent *event){ omittagHoist_ = 0; if (doNothing(event)) return; Char c = event->re(); withNamedCharRef(&c, 1, event->location()); delete event;}void CopyEventHandler::sSep(SSepEvent *event){ if (doNothing(event)) return; withNamedCharRef(event->data(), event->dataLength(), event->location()); delete event;}void CopyEventHandler::ignoredRs(IgnoredRsEvent *event){ if (doNothing(event)) return; Char c = event->rs(); withNamedCharRef(&c, 1, event->location()); delete event;}void CopyEventHandler::startElement(StartElementEvent *event){ mustOmitEnd_ = event->mustOmitEnd(); const Markup *markup = event->markupPtr(); if (!markup) { if (normalizeFlags_ & normalizeExpand) { if (outputEntityLevel_ > entityLevel_ - omittagHoist_) { delete event; return; } if (omittagHoist_ >= entityStack_.size()) os_ = topOs_; } else if (entityLevel_ - omittagHoist_ != outputEntityLevel_) { delete event; return; } } else { omittagHoist_ = 0; if (doNothing(event)) return; } if (normalizeFlags_ & normalizeExpandAll) handleChange(); if (markup) { Boolean hadName = 0; Boolean closed = 1; MarkupIter iter(*markup); while (iter.valid()) { switch (iter.type()) { case Markup::delimiter: switch (iter.delimGeneral()) { case Syntax::dTAGC: closed = 1; if (!hadName) { StringC nameBuf; StringC tag(elementTypeOrigName(event->elementType(), nameBuf)); if (normalizeFlags_ & normalizeEmptytag) { handleChange(); os() << tag; tag.resize(0); } unspecifiedAttributeValues(event->attributes(), tag); } os() << syntax_->delimGeneral(iter.delimGeneral()); break; case Syntax::dNESTC: closed = 1; if (normalizeFlags_ & normalizeNet) { handleChange(); os() << syntax_->delimGeneral(Syntax::dTAGC); break; } // fall through default: os() << syntax_->delimGeneral(iter.delimGeneral()); break; } iter.advance(); break; case Markup::name: { ASSERT(!hadName); const ElementType *elementType = event->elementType(); if (elementType->index() >= elementTypeOrigNames_.size()) elementTypeOrigNames_.resize(elementType->index() + 1); StringC &elementTypeOrigName = elementTypeOrigNames_[elementType->index()]; if (elementTypeOrigName.size() == 0) { elementTypeOrigName.assign(iter.charsPointer(), iter.charsLength()); // add rank if missing elementTypeOrigName.append(event->name().data() + elementTypeOrigName.size(), event->name().size() - elementTypeOrigName.size()); } os() << iter; if (normalizeFlags_ & normalizeRank) { for (size_t i = iter.charsLength(); i < event->name().size(); i++) { handleChange(); os().put(event->name()[i]); } } attributeSpecList(iter, event->attributes()); hadName = 1; } break; case Markup::s: os() << iter; iter.advance(); break; default: CANNOT_HAPPEN(); } } if (!closed && (normalizeFlags_ && normalizeUnclosed)) { handleChange(); os() << syntax_->delimGeneral(Syntax::dTAGC); } } else if (normalizeFlags_ & normalizeOmittag) { if (inSpecialMarkedSection_) { reportTagInSpecialMarkedSection(event->location()); return; } handleChange(); StringC nameBuf; os() << syntax_->delimGeneral(Syntax::dSTAGO) << elementTypeOrigName(event->elementType(), nameBuf); unspecifiedAttributeValues(event->attributes(), StringC()); os() << syntax_->delimGeneral(Syntax::dTAGC); } delete event; if (entityStack_.size() > 0 && os_ == topOs_) os_ = &entityStack_.back().str;}void CopyEventHandler::attributeSpecList(MarkupIter &iter, const AttributeList &atts){ size_t nAtt = atts.size(); unsigned i; unsigned *attIndex; if (atts.nSpec()) { attIndex = new unsigned[atts.nSpec()]; for (i = 0; i < atts.nSpec(); i++) attIndex[i] = unsigned(-1); for (i = 0; i < nAtt; i++) if (atts.specified(i)) attIndex[atts.specIndex(i)] = i; } else attIndex = 0; Boolean hadAttname = 0; i = 0; StringC nameBuf; for (iter.advance(); iter.valid(); iter.advance()) switch (iter.type()) { case Markup::name: os() << iter; hadAttname = 1; break; case Markup::s: os() << iter; break; case Markup::attributeValue: if (!hadAttname && attIndex && attIndex[i] != unsigned(-1) && (normalizeFlags_ & (normalizeAttname | normalizeAttvalue))) { handleChange(); os() << generalName(atts.name(attIndex[i]), nameBuf) << syntax_->delimGeneral(Syntax::dVI); } if (normalizeFlags_ & normalizeAttvalue) { handleChange(); os() << syntax_->delimGeneral(Syntax::dLIT) << iter << syntax_->delimGeneral(Syntax::dLIT); } else os() << iter; hadAttname = 0; i++; break; case Markup::literal: literal(iter.text()); i++; hadAttname = 0; break; case Markup::delimiter: if (iter.delimGeneral() == Syntax::dVI) os() << syntax_->delimGeneral(iter.delimGeneral()); else { unspecifiedAttributeValues(atts, StringC()); delete [] attIndex; return; } break; default: CANNOT_HAPPEN(); }}void CopyEventHandler::unspecifiedAttributeValues(const AttributeList &atts, const StringC &beforeFirst){ if (normalizeFlags_ & (normalizeCurrent|normalizeAttspec)) { Boolean first = 1; size_t nAtt = atts.size(); StringC nameBuf; for (unsigned i = 0; i < nAtt; i++) { const Text *text; if (!atts.specified(i) && ((normalizeFlags_ & normalizeAttspec) || atts.current(i)) && atts.value(i) && (text = atts.value(i)->text()) != 0) { if (first) { handleChange(); os() << beforeFirst; first = 0; } os().put(syntax_->standardFunction(Syntax::fSPACE)); os() << generalName(atts.name(i), nameBuf) << syntax_->delimGeneral(Syntax::dVI); Boolean lita; if (text->delimType(lita)) literal(*text); else { if (normalizeFlags_ & normalizeAttvalue) { os() << syntax_->delimGeneral(Syntax::dLIT) << text->string() << syntax_->delimGeneral(Syntax::dLIT); } else os() << text->string(); } } } }}void CopyEventHandler::literal(const Text &text){ TextIter iter(text); TextItem::Type type; const Char *p; size_t n; const Location *loc; StringC delim; Boolean lita; if (!text.delimType(lita)) CANNOT_HAPPEN(); delim = syntax_->delimGeneral(lita ? Syntax::dLITA : Syntax::dLIT); os() << delim; int level = 0; while (iter.next(type, p, n, loc)) { switch (type) { case TextItem::ignore: case TextItem::data: case TextItem::nonSgml: if (!level) { const Char *orig; if (loc->origin()->origChars(orig)) writeData(orig, n, loc->origin()->parent()); else writeData(p, n, *loc); } break; case TextItem::cdata: case TextItem::sdata: if (!level) entityRef(loc->origin()->asEntityOrigin()); break; case TextItem::entityStart: if (!level++) entityRef(loc->origin()->asEntityOrigin()); break; case TextItem::entityEnd: level--; break; case TextItem::startDelim: case TextItem::endDelim: case TextItem::endDelimA: break; } } Location delimLoc; if (!text.endDelimLocation(delimLoc)) CANNOT_HAPPEN(); withNamedCharRef(delim, delimLoc);}void CopyEventHandler::endElement(EndElementEvent *event){ if (!emptyElementNormal_ && mustOmitEnd_) { delete event; mustOmitEnd_ = 0; return; } const Markup *markup = event->markupPtr(); if (!markup) { if (normalizeFlags_ & normalizeExpand) { if (outputEntityLevel_ > entityLevel_ - omittagHoist_) { delete event; return; } if (omittagHoist_ >= entityStack_.size()) os_ = topOs_; } else if (entityLevel_ - omittagHoist_ != outputEntityLevel_) { delete event; return; } } else { omittagHoist_ = 0; if (doNothing(event)) return; } if (normalizeFlags_ & normalizeExpandAll) handleChange(); if (markup) { Boolean closed = 0; Boolean hadAttname = 0; for (MarkupIter iter(*markup); iter.valid(); iter.advance()) switch (iter.type()) { case Markup::s: os() << iter; break; case Markup::name:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -