123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- * tedi2tex library code
- * Copyright (C) <2022> <alkeon> [alkeon@autistici.org]
-
- * Texdi is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Texdi is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with tedi2tex. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <sstream>
- #include "tedi2tex.h"
- #include "../tedi2lang/tedi2lang.h"
- #include "../tedi2lang/exception.h"
- using namespace std;
- #define BLOCK 2
- #define IMAGE 1
- #define LINK 0
- #define NO_TAG -1
- tedi2tex::tedi2tex(tags_definition td): tedi2lang(td){}
- tedi2tex::tedi2tex(): tedi2lang(default_tags_value()){}
- tags_definition tedi2tex::default_tags_value(){
-
- tags_definition td;
- td.start_heading_first_level_tag = "\\section{";
- td.start_heading_second_level_tag = "\\subsection{";
- td.start_heading_third_level_tag = "\\subsubsection{";
- td.start_heading_fourth_level_tag = "\\subsubsection{";
- td.end_heading_first_level_tag = "}";
- td.end_heading_second_level_tag = "}";
- td.end_heading_third_level_tag = "}";
- td.end_heading_fourth_level_tag = "}";
- td.start_list_tag = "\\begin{itemize}";
- td.list_item_tag = "\\item ";
- td.end_list_tag = "\\end{itemize}";
- td.start_container_tag = "";
- td.middle_container_tag = "";
- td.end_container_tag = "";
- td.start_link_tag = "\\href{";
- td.middle_link_tag = "}{";
- td.end_link_tag = "}";
- td.start_image_tag = "\\begin{figure}[h!]\n\\centering\n\\includegraphics[width=1\\textwidth]{";
- td.middle_image_tag = "";
- td.end_image_tag = "";
- td.start_table_tag = "";
- td.end_table_tag = "\\hline\n\\end{longtable}\n";
- td.start_table_row_tag = "\\hline";
- td.end_table_row_tag = "\\tabularnewline";
- td.start_table_data_tag = " & ";
- td.end_table_data_tag = "";
- td.end_paragraph_tag = "\n";
- return td;
- }
- /*
- * Main logic converting line.
- *
- */
- string tedi2tex::convert_line(string& line) {
- if(line[0] != '<') {
- escape_underscores(line);
- string end_table = convert_end_table(line);
- size_t hash = line.find('#');
- if(found(hash) && is_first_tag(line, hash))
- return end_table + convert_line_heading(line, hash);
- else {
- size_t ul = line.find("__");
- if(found(ul))
- return end_table + convert_line_list_start(line);
- else {
- size_t li = line.find("--");
- if(found(li) && _is_unordered_list)
- convert_line_list_item(line, li);
-
- size_t ul_end = line.find(",,");
- if(found(ul_end) && _is_unordered_list)
- return end_table + convert_line_list_end(line);
- else{
- if(line[0] == '"')
- convert_line_quote(line);
- else
- convert_unquoted_tags(line);
-
- size_t first_pipe = line.find("|");
- if(found(first_pipe))
- return convert_line_table(line, first_pipe);
- else
- return end_table + convert_line_ending(line);
-
- }
- }
- }
- } else
- return convert_end_table_control_tags(line) + convert_line_control_tags(line);
-
- }
- /*
- * Deletes heading tag and insert image tag
- * - ([caption] image.png)
- * - image::image.png[caption]
- *
- */
- void tedi2tex::convert_line_image(string& line) {
- size_t start_tag = get_not_escaped_tag(line, "([");
- if(found(start_tag) && !is_tag_escaped(line, start_tag)) {
- line = line.erase(start_tag, 2);
- size_t square_bracket = get_not_escaped_tag(line, "] ");
- if(found(square_bracket) && !is_tag_escaped(line, square_bracket)) {
- string caption = line.substr(start_tag, square_bracket - start_tag);
- line = line.erase(start_tag, square_bracket + 2 - start_tag);
- line = line.insert(start_tag, _start_image_tag);
- int last_parenthesis = correct_position(line, start_tag + _start_image_tag.size(), '(', ')');
- if(found(last_parenthesis)) {
- line = line.erase(last_parenthesis, 1);
- line = line.insert(last_parenthesis, "}\n\\caption{" + caption + "}\n\\end{figure}");
- } else
- throw Invalid("Missing ')' in images tag.",line);
- } else
- throw Invalid("Missing ']' in images tag.",line);
- } else
- throw Invalid("Missing images tag.",line);
- }
- /*
- * Deletes block tag and insert block tag
- *
- */
- void tedi2tex::convert_line_block(string& line) {
- size_t start_tag = get_not_escaped_tag(line, "{(");
- if(found(start_tag) && !is_tag_escaped(line, start_tag)) {
- line = line.erase(start_tag, 2);
- line = line.insert(start_tag, _start_container_tag);
- size_t parenthesis = get_not_escaped_tag(line, ") ");
- if(found(parenthesis) && !is_tag_escaped(line, parenthesis)) {
- line = line.erase(start_tag, parenthesis - start_tag + 2);
- size_t end_tag = correct_position(line, start_tag, '{', '}');
- if(found(end_tag))
- line = line.erase(end_tag, 1);
- else
- ++_open_brackets;
-
- } else
- throw Invalid("Missing ')' in block tag.",line);
- } else
- throw Invalid("Missing block tag.",line);
- _has_block = true;
- }
- /*
- * Start or continue table conversion
- *
- */
- string tedi2tex::convert_line_table(string& line, size_t first_pipe) {
- string return_text;
- if(!_is_converting_table) {
- if(first_pipe != line.rfind("|")) {
- return_text += get_table_start_tag(line);
- _is_converting_table = true;
- return return_text + convert_line_table_row(line);
- } else
- return convert_line_ending(line);
- }else
- return return_text + convert_line_table_row(line);
-
- return return_text;
- }
- /*
- * Convert every cell of one table row
- *
- */
- string tedi2tex::convert_line_table_row(string& line) {
- size_t pipe = line.find("|");
- if(found(pipe)) {
- ++pipe;
- string return_text = _start_table_row_tag + "\n";
- line = line.substr(pipe, line.size() - 1);
- pipe = line.find("|");
- if(found(pipe)) {
- int size = line.size() - 1;
- if(line[size] == '|') {
- bool start = true;
- while(found(pipe) && line[size] == '|') {
- if(start) {
- return_text += strip_escaping(line.substr(0, pipe));
- start = false;
- } else
- return_text += _start_table_data_tag + strip_escaping(line.substr(0, pipe));
- ++pipe;
- line = line.substr(pipe, size);
- pipe = line.find("|");
- size = line.size() - 1;
- }
- return return_text + _end_table_row_tag + "\n";
- }else
- throw Invalid("Table not correctly written\n"
- "Maybe there's a whitespace at end of line", line);
- }else
- throw Invalid("Expected '|' in table", line);
- }else
- throw Invalid("Expected '|' in table", line);
- }
- string tedi2tex::convert_line_control_tags(string& line){
- if(line[1] != '!') {
- if(line[1] == '>') {
- line = line.erase(0,2);
- return line + "\n";
- } else if(line[1] == '+') {
- line = line.erase(0,2);
- return "\\begin{verbatim}\n" + line + "\n\\end{verbatim}\n\n";
- } else if(!found(line.find("!")) && !found(line.find("¡"))) {
- line = line.erase(0,1);
- return "\\verb!" + line + "!\n";
- } else if(!found(line.find("}")) && !found(line.find("{"))) {
- line = line.erase(0,1);
- return "\\verb{" + line + "}\n";
- } else {
- line = line.erase(0, 1);
- return "\\begin{verbatim}\n" + line + "\n\\end{verbatim}\n\n";
- }
- } else
- return "";
-
- }
- string tedi2tex::get_table_start_tag(string& line) {
- int columns = get_table_columns(line);
- string start_table_tag = "\\begin{longtable}{";
- double size_per_column = 0.9 / columns;
- for(int i = 0; i < columns; ++i)
- start_table_tag += "|p{" + to_string(size_per_column) + "\\linewidth}";
- start_table_tag += "|}\n";
- return start_table_tag;
- }
- int tedi2tex::get_table_columns(string line){
- int data = 0;
- size_t pipe = line.find("|");
- int size = line.size() - 1;
- while(found(pipe) && (line[size] == '|' || line[size - 1] == '|')) {
- ++pipe;
- line = line.substr(pipe, line.size() - 1);
- pipe = line.find("|");
- size = line.size() - 1;
- ++data;
- }
- return data - 1;
- }
- void tedi2tex::escape_underscores(string& line) {
- size_t underscore = line.find('_');
- while(found(underscore)) {
- if(underscore + 1 >= line.size() || line[underscore + 1] != '_')
- line = line.insert(underscore, 1, '\\');
- underscore = line.find('_', underscore + 2);
- }
- }
|