SAWYER_EXPORT void PodFormatter::endTag(std::ostream &out, const Tag::Ptr &tag, const TagArgs &args) { ASSERT_forbid(tagStack_.empty()); ASSERT_require(tagStack_.back()==tag); tagStack_.pop_back(); if (tag->type() == DIVIDING) out <<(atBeginningOfLine_?"":"\n") <<"\n"; if (tag->name() == "list") { out <<"=back\n\n"; } else if (tag->name() == "prose" || tag->name() == "nonprose") { out <<"=back\n\n"; textModePop(); } }
SAWYER_EXPORT bool PodFormatter::beginTag(std::ostream &out, const Tag::Ptr &tag, const TagArgs &args) { tagStack_.push_back(tag); if (tag->type() == DIVIDING) { out <<(atBeginningOfLine_?"":"\n") <<"\n"; atBeginningOfLine_ = true; } if (tag->name() == "prose") { checkArgs(tag, 1, args); out <<"=over\n\n"; textModePush(PROSE); } else if (tag->name() == "nonprose") { checkArgs(tag, 1, args); out <<"=over\n\n"; textModePush(NONPROSE); } else if (tag->name() == "section") { // Nested sections, but only if the body is not empty. checkArgs(tag, 2, args); size_t level = nested() + 1; if (level > 4) throw std::runtime_error("POD formatter can handle at most four levels of section nesting"); std::ostringstream arg0, arg1; arg0 <<"=head" <<level <<" "; atBeginningOfLine_ = false; args[0]->emit(arg0, self()); arg0 <<"\n\n"; atBeginningOfLine_ = true; args[1]->emit(arg1, self()); if (hasNonSpace(arg1.str())) out <<arg0.str() <<arg1.str(); return false; // no recursion } else if (tag->name() == "list") { out <<"=over\n\n"; atBeginningOfLine_ = true; } else if (tag->name() == "bullet") { checkArgs(tag, 1, args); out <<"=item * "; atBeginningOfLine_ = false; } else if (tag->name() == "numbered") { checkArgs(tag, 1, args); out <<"=item 1 "; atBeginningOfLine_ = false; } else if (tag->name() == "named") { checkArgs(tag, 2, args); out <<"=item "; args[0]->emit(out, self()); out <<"\n\n"; atBeginningOfLine_ = true; args[1]->emit(out, self()); return false; } else if (tag->name() == "comment") { return false; } else if (tag->name() == "emphasis") { checkArgs(tag, 1, args); out <<(nested() % 2 ? 'B' : 'I') <<'<'; atBeginningOfLine_ = false; args[0]->emit(out, self()); out <<">"; atBeginningOfLine_ = false; return false; } else if (tag->name() == "variable") { checkArgs(tag, 1, args); out <<"I<"; atBeginningOfLine_ = false; args[0]->emit(out, self()); out <<">"; atBeginningOfLine_ = false; return false; } else if (tag->name() == "link") { // second arg (text) is ignored; only link is shown checkArgs(tag, 2, args); out <<"L<"; atBeginningOfLine_ = false; args[0]->emit(out, self()); out <<">"; atBeginningOfLine_ = false; return false; } else if (tag->name() == "verbatim") { } else { throw std::runtime_error("unrecognized markup tag \"" + tag->name() + "\" for Perl POD formatter"); } return true; }