kashirin-alex commented on a change in pull request #2241: URL: https://github.com/apache/thrift/pull/2241#discussion_r495058967
########## File path: compiler/cpp/src/thrift/generate/t_markdown_generator.cc ########## @@ -0,0 +1,1085 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string> +#include <fstream> +#include <iostream> +#include <vector> +#include <map> +#include <array> + +#include <stdlib.h> +#include <sys/stat.h> +#include <sstream> +#include "thrift/platform.h" +#include "thrift/generate/t_generator.h" + +using std::map; +using std::ofstream; +using std::ostringstream; +using std::pair; +using std::string; +using std::stringstream; +using std::vector; + +//using std::endl; +static const string endl = "\n"; // avoid ostream << std::endl flushes + +std::string str_to_id(const std::string& s) { + std::string id; + for(auto chr=s.begin();chr<=s.end(); ++chr) { + if(*chr == '.' || *chr == 0) + continue; + id += std::tolower(*chr); + } + return id; +} + + +enum input_type { INPUT_UNKNOWN, INPUT_UTF8, INPUT_PLAIN }; + +/** + * MARKDOWN code generator + * + * mostly copy/pasting/tweaking from t_html_generator's work. + */ +class t_markdown_generator : public t_generator { +public: + t_markdown_generator(t_program* program, + const std::map<std::string, std::string>& parsed_options, + const std::string& option_string) + : t_generator(program) { + + (void)option_string; + std::map<std::string, std::string>::const_iterator iter; + + unsafe_ = false; + for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { + if( iter->first.compare("noescape") == 0) { + unsafe_ = true; + } else if( iter->first.compare("suffix") == 0 && !iter->second.empty()) { + extension_ = "." + iter->second; + } else { + throw "unknown option markdown:" + iter->first; + } + } + + + out_dir_base_ = "gen-markdown"; + input_type_ = INPUT_UNKNOWN; + + escape_.clear(); + escape_['&'] = "&"; + escape_['<'] = "<"; + escape_['>'] = ">"; + escape_['"'] = """; + escape_['\''] = "'"; + + init_allowed__markup(); + } + + void generate_program() override; + void generate_program_toc(); + void generate_program_toc_row(t_program* tprog); + void generate_program_toc_rows(t_program* tprog, std::vector<t_program*>& finished); + void generate_index(); + std::string escape_html(std::string const& str); + std::string escape_html_tags(std::string const& str); + std::string make_file_link(std::string name); + std::string make_file_name(std::string name); + bool is_utf8_sequence(std::string const& str, size_t firstpos); + void detect_input_encoding(std::string const& str, size_t firstpos); + void init_allowed__markup(); + + /** + * Program-level generation functions + */ + + void generate_typedef(t_typedef* ttypedef) override; + void generate_enum(t_enum* tenum) override; + void generate_const(t_const* tconst) override; + void generate_struct(t_struct* tstruct) override; + void generate_service(t_service* tservice) override; + void generate_xception(t_struct* txception) override; + + void print_doc(t_doc* tdoc); + int print_type(t_type* ttype); + void print_const_value(t_type* type, t_const_value* tvalue); + void print_fn_args_doc(t_function* tfunction); + +private: + ofstream_with_content_based_conditional_update f_out_; + std::string current_file_; + input_type input_type_; + std::map<std::string, int> allowed_markup; + bool unsafe_; + std::string extension_; +}; + +/** + * Emits the Table of Contents links at the top of the module's page + */ +void t_markdown_generator::generate_program_toc() { + f_out_ << "| Module | Services & Functions | Data types | Constants |" << endl + << "| --- | --- | --- | --- |" << endl; + generate_program_toc_row(program_); + f_out_ << endl; +} + +/** + * Recurses through from the provided program and generates a ToC row + * for each discovered program exactly once by maintaining the list of + * completed rows in 'finished' + */ +void t_markdown_generator::generate_program_toc_rows(t_program* tprog, + std::vector<t_program*>& finished) { + for (auto & iter : finished) { + if (tprog->get_path() == iter->get_path()) { + return; + } + } + finished.push_back(tprog); + generate_program_toc_row(tprog); + vector<t_program*> includes = tprog->get_includes(); + for (auto & include : includes) { + generate_program_toc_rows(include, finished); + } +} + +/** + * Emits the Table of Contents links at the top of the module's page + */ +void t_markdown_generator::generate_program_toc_row(t_program* tprog) { + // "| Module | Services | Data types | Constants | + vector<std::array<string, 4>> filling; + + string fname = make_file_name(tprog->get_name()); + filling.emplace_back(); + auto fill = &filling.back(); + (*fill)[0] = tprog->get_name(); + + if (!tprog->get_services().empty()) { + vector<t_service*> services = tprog->get_services(); + vector<t_service*>::iterator sv_iter; + for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) { + if(sv_iter != services.begin()) { + filling.emplace_back(); + fill = &filling.back(); + } + string name = get_service_name(*sv_iter); + (*fill)[1] = "[" + name + "](" + make_file_link(fname) + "#service" + str_to_id(name) + ")"; Review comment: Missing Hyphen after `#service` `#service` > `#service-` ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
