/** * Copyright (c) 2022, Timothy Stack * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Timothy Stack nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef lnav_md4cpp_hh #define lnav_md4cpp_hh #include #include #include #include "base/intern_string.hh" #include "base/result.h" #include "mapbox/variant.hpp" #include "md4c/md4c.h" namespace md4cpp { struct xml_entity { std::string xe_chars; }; struct xml_entity_map { std::map xem_entities; }; struct emoji { std::string e_shortname; std::string e_value; }; struct emoji_map { std::vector em_emojis; std::unordered_map> em_shortname2emoji; }; class event_handler { public: virtual ~event_handler() = default; struct block_doc {}; struct block_quote {}; struct block_hr {}; struct block_html {}; struct block_p {}; struct block_thead {}; struct block_tbody {}; struct block_tr {}; struct block_th {}; using block = mapbox::util::variant; virtual Result enter_block(const block& bl) = 0; virtual Result leave_block(const block& bl) = 0; struct span_em {}; struct span_strong {}; struct span_code {}; struct span_del {}; struct span_u {}; using span = mapbox::util::variant; virtual Result enter_span(const span& bl) = 0; virtual Result leave_span(const span& bl) = 0; virtual Result text(MD_TEXTTYPE tt, const string_fragment& sf) = 0; }; namespace details { Result parse(const string_fragment& sf, event_handler& eh); } template class typed_event_handler : public event_handler { public: virtual T get_result() = 0; }; template Result parse(const string_fragment& sf, typed_event_handler& eh) { TRY(details::parse(sf, eh)); return Ok(eh.get_result()); } const xml_entity_map& get_xml_entity_map(); const emoji_map& get_emoji_map(); std::string escape_html(const std::string& content); namespace literals { inline std::string operator"" _emoji(const char* str, std::size_t len) { const auto& em = get_emoji_map(); const auto key = std::string(str, len); auto iter = em.em_shortname2emoji.find(key); assert(iter != em.em_shortname2emoji.end()); return iter->second.get().e_value; } } // namespace literals } // namespace md4cpp #endif