// Copyright 1998,1999 Zanshin Inc. // The contents of this file are subject to the Zanshin Public License Version // 1.0 (the "License"); you may not use this file except in compliance with the // License. You should have received a copy of the License with Latte; see // the file COPYING. You may also obtain a copy of the License at // . // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the // License. // // The Original Code is Latte. // // The Initial Developer of the Original Code is Zanshin, Inc. #include #include #include #include #include #include using namespace std; static bool in_pre = 0; static bool in_html = 0; void LatteHtml_PreObj::visit(Latte_Visitor &visitor) { Restorer in_pre_restorer(in_pre); in_pre = 1; nested_obj()->visit(visitor); } Refcounter LatteHtml_PreObj::do_eval(Latte_Activation &activation) { if (self_evaluating()) return Refcounter(this); return Refcounter(new LatteHtml_PreObj(*(nested_obj()->eval(activation)))); } void LatteHtml_HtmlObj::visit(Latte_Visitor &visitor) { Restorer in_html_restorer(in_html); in_html = 1; nested_obj()->visit(visitor); } Refcounter LatteHtml_HtmlObj::do_eval(Latte_Activation &activation) { if (self_evaluating()) return Refcounter(this); return Refcounter(new LatteHtml_HtmlObj(*(nested_obj()->eval(activation)))); } class PreOp : public Latte_Operator { public: const shstring &name() const { static const shstring n = "_pre"; return n; } protected: Refcounter apply(const Latte_Wstate &wstate, const Latte_FileLoc &fileloc, const Latte_List::const_iterator &args, const Latte_List::const_iterator &args_end, Latte_Activation &activation) const { Refcounter result_list(new Latte_List); for (Latte_List::const_iterator i = args; i != args_end; ++i) result_list->push_back((*i)->eval(activation)); return Refcounter(new LatteHtml_PreObj(*(Latte_WsNode::wrap(*result_list, wstate)))); } }; class HtmlOp : public Latte_Operator { public: const shstring &name() const { static const shstring n = "html"; return n; } protected: Refcounter apply(const Latte_Wstate &wstate, const Latte_FileLoc &fileloc, const Latte_List::const_iterator &args, const Latte_List::const_iterator &args_end, Latte_Activation &activation) const { Refcounter result_list(new Latte_List); for (Latte_List::const_iterator i = args; i != args_end; ++i) result_list->push_back((*i)->eval(activation)); Refcounter wsnode(new Latte_WsNode(*result_list, wstate)); return Refcounter(new LatteHtml_HtmlObj(*(Latte_WsNode::wrap(*result_list, wstate)))); } }; void LatteHtml_HtmlVisitor::visit_str(Latte_Str &str) { static bool ever_called = 0; static bool p_begun = 0; const Latte_Wstate &ws = suggest_wstate(str.wstate()); if (ever_called) { bool do_p = (!in_pre && (ws.newlines() > 1)); if (do_p && p_begun && m_close_par) m_out << "

"; m_out << ws; if (do_p) { m_out << "

"; p_begun = 1; } } ever_called = 1; if (in_html) m_out << str.str(); else for (Latte_Str::const_iterator i = str.begin(); i != str.end(); ++i) { const char &c = *i; switch (c) { case '<': m_out << "<"; break; case '>': m_out << ">"; break; case '&': m_out << "&"; break; case '"': m_out << """; break; default: m_out << c; break; } } } void latte_html(const char *lang, bool strict, bool fragment, bool no_default, bool close_par, unsigned long log_flags, const deque::const_iterator &loads_begin, const deque::const_iterator &loads_end, const char *filename, istream &in, ostream &out) { srandom(getpid() ^ time(0)); // should the UI do this? latte_init(1); Latte_Reader reader(in, filename); latte_log_flags = log_flags; reader.install_standard_definitions(); reader.define_global("__FILE__", Refcounter(new Latte_Str(Latte_Wstate(), Latte_FileLoc(), filename))); reader.define_global("html", Refcounter(new HtmlOp)); reader.define_global("_pre", Refcounter(new PreOp)); reader.define_global("strict-html4", strict ? latte_true() : latte_false()); if (!no_default) { latte_load_library("standard", reader.global_activation()); latte_load_library("html", reader.global_activation()); } for (deque::const_iterator i = loads_begin; i != loads_end; ++i) latte_load_library(*i, reader.global_activation()); LatteHtml_HtmlVisitor visitor(out, close_par); if (!fragment) { out << "" << endl; out << "" << endl; out << "" << endl; out << "" << endl; } reader.process(visitor); #if 0 if (!reader.processed()) { const Latte_Obj &unprocessed = reader.unprocessed(); const Latte_Tangible *tangible = unprocessed.as_tangible(); const Latte_Group *group = unprocessed.as_group(); const Latte_Assignment *assignment = unprocessed.as_assignment(); if (group) throw Latte_Reader::IncompleteGroup(group->fileloc()); if (assignment) throw Latte_Reader::IncompleteAssignment(assignment->fileloc()); if (tangible) throw Latte_Reader::Incomplete(tangible->fileloc()); throw Latte_Reader::Incomplete(Latte_FileLoc()); } #endif out << endl; if (!fragment) out << "" << endl; }