static tree parse_item (string s, int &i, int item_indent) { int text_indent= item_indent, n= N(s); while (i<n && is_blank (s[i])) i++; if (is_new_item (s, i)) { text_indent++; while (s[i] == '-') i++; } while (i<n && is_spacing (s[i])) { if (s[i] == ' ') text_indent++; i++; } tree r (CONCAT); r << compound ("item"); string line= ""; string tmp= parse_line (s, i, text_indent); if (tmp != "") line << tmp; while (can_parse_line (s, i, text_indent)) { tmp= parse_line (s, i, text_indent); if (tmp != "") line << "\n" << tmp; } r << coqdoc_to_tree (line); return r; }
static int parse_indent (string s, int i) { int indent= 0, n= N(s); while (i<n && is_spacing (s[i])) i++, indent++; if (i<n && s[i] != '\n') return indent; else return -1; }
static bool is_list_begining (string s, int i) { int n= N(s); if (!(i<n && s[i] == '\n')) return false; i++; while (i<n && is_spacing (s[i])) i++; return is_new_item (s, i); }
static array<string> split_command (string s) { int start= 0, i=0, n= N(s); array<string> r; while (i<n) { if (s[i] == '.' && i+1<n && is_spacing (s[i+1])) { r << s(start, ++i); while (i<n && is_spacing (s[i])) i++; start= i; } else if (start_comment (s, i)) parse_comment (s, i); else i++; } if (start < n) r << s(start, n); return r; }
static bool is_star_rule (string s, int i) { int n= N(s), stars=0, blanks= 0; i++; while (i<n) { if (s[i] == '*') stars++; else if (is_spacing (s[i])) blanks++; else break; i++; } return (i >= n || (i>0 && test (s, i-1, "*)"))) && stars > blanks; }
static bool end_vernac_command (string s, int i) { int n= N(s); if (!(i<n && s[i] == '.')) return false; i++; while (i<n) { if (is_spacing (s[i])) i++; else if (start_comment (s, i)) parse_comment (s, i); else break; } return i >= n || s[i] == '\n'; }
static sv_<ss_> split_string_to_clean_ui_pieces(const ss_ &s, size_t piece_len) { sv_<ss_> result; size_t start_from = 0; for(;;){ if(start_from >= s.size()) break; size_t start_from_instead = start_from; for(size_t i=start_from; i<s.size(); i++){ if((s[i] < 'a' || s[i] > 'z') && (s[i] < 'A' || s[i] > 'Z') && (s[i] < '0' || s[i] > '9')){ start_from_instead = i + 1; continue; } break; } if(start_from_instead >= s.size()){ result.push_back(s.substr(start_from)); break; } if(start_from_instead >= s.size() - piece_len){ result.push_back(s.substr(start_from_instead)); break; } size_t end_at = start_from_instead + piece_len; if(s.size() > end_at + 2 && end_at >= 3){ if(is_spacing(s[end_at-2]) && !is_spacing(s[end_at-1]) && !is_spacing(s[end_at]) && (is_spacing(s[end_at+1]) || is_spacing(s[end_at+2]))){ end_at = end_at - 1; } else if(is_spacing(s[end_at-3]) && !is_spacing(s[end_at-2]) && !is_spacing(s[end_at-1]) && !is_spacing(s[end_at]) && (is_spacing(s[end_at+1]) || is_spacing(s[end_at+2]))){ end_at = end_at - 2; } } result.push_back(s.substr(start_from_instead, end_at - start_from_instead)); start_from = end_at; } return result; }
static tree coqdoc_to_tree (string s) { bool newline= true; int i=0, n= N(s); tree coqdoc (DOCUMENT), line (CONCAT); if (starts (s, "(**")) { line << "(**"; i+= 3; } while (i < n) { if (test (s, i, "[[\n")) { add_line (line, coqdoc); tree vernac= vernac_to_tree (parse_delimited (s, i, "[[\n", "\n]]", false)); coqdoc << compound ("coqdoc-vernac", vernac); newline= true; } else if (s[i] == '[') line << compound ("coqdoc-coq", from_verbatim (parse_delimited (s, i, "[", "]", false))); else if (newline && (test (s, i, "**** ") || test (s, i, "*** ") || test (s, i, "** ") || test (s, i, "* "))) { string header= "section"; if (test (s, i, "** ")) header= "subsection"; if (test (s, i, "*** ")) header= "subsubsection"; if (test (s, i, "**** ")) header= "paragraph"; while (i<n && s[i] == '*') i++; while (i<n && is_spacing (s[i])) i++; int start= i; while (i<n && (s[i] != '\n' && !test (s, i, "*)"))) i++; line << compound (header, coqdoc_to_tree (s (start, i))); } else if (newline && is_defining_pretty_printing (s, i)) { string str= parse_delimited (s, i, "(*", "*)", false); parse_pretty_printing_definition (str); } else if (newline && is_removing_pretty_printing (s, i)) { string str= parse_delimited (s, i, "(*", "*)", false); parse_pretty_printing_removal (str); } else if (test (s, i, "%%")) { line << "%"; newline= false; i+= 2; } else if (test (s, i, "$$")) { line << "$"; newline= false; i+= 2; } else if (test (s, i, "##")) { line << "#"; newline= false; i+= 2; } else if (s[i] == '#' || s[i] == '%' || s[i] == '$') { newline= false; char delim= s[i]; string ext= unescape_coqdoc (parse_delimited (s, i, delim)); tree tm; if (delim == '#') tm= compound ("coqdoc-html", generic_to_tree (ext, "html-snippet")); else if (delim == '$') tm= compound ("coqdoc-latex", generic_to_tree ("$"*ext*"$", "latex-snippet")); else if (delim == '%') tm= compound ("coqdoc-latex", generic_to_tree (ext, "latex-snippet")); if (is_multi_paragraph (tm)) { add_line (line, coqdoc); coqdoc << tm; } else line << tm; } else if (is_list_begining (s, i)) { tree list= parse_list (s, i); add_line (line, coqdoc); coqdoc << list; newline= true; } else if (test (s, i, "\n<<")) { add_line (line, coqdoc); string parsed= parse_delimited (s, i, "\n<<", "\n>>", false); if (N(parsed) > 0 && parsed[0] == '\n') parsed= parsed(1, N(parsed)); tree verb= verbatim_to_tree (parsed, false, "SourceCode"); if (is_atomic (verb)) verb= document (verb); coqdoc << compound ("coqdoc-verbatim", verb); newline= true; } else if (test (s, i, "<<")) { string parsed= parse_delimited (s, i, "<<", ">>", false); tree verb= verbatim_to_tree (parsed, true, "SourceCode"); line << compound ("coqdoc-verbatim", verb); } else if (s[i] == '_' && (i == 0 || !start_ident(s[i-1]))) { line << coqdoc_parse_emphasis (s, i); newline= false; } else if (test (s, i, "----")) { i+= 4; add_line (line, coqdoc); coqdoc << compound ("hrule"); while (i<n && s[i] == '-') i++; newline= true; } else if (s[i] == '\n') { add_line (line, coqdoc); i++; if (is_whiteline (s, i)) { coqdoc << ""; do skip_whiteline (s, i); while (is_whiteline (s, i)); i--; } newline= true; } else if (s[i] == '<') { line << "<less>"; i++; newline= false; } else if (s[i] == '>') { line << "<gtr>"; i++; newline= false; } else { if (!is_spacing (s[i])) newline= false; int start= i; decode_from_utf8 (s, i); line << from_verbatim (s(start, i)); } } if (N(line) > 0) add_line (line, coqdoc); if (N(coqdoc) == 0) return ""; else if (N(coqdoc) == 1) return coqdoc[0]; else return coqdoc; }
static void skip_whiteline (string s, int &i) { int n= N(s); while (i<n && is_spacing (s[i])) i++; i++; }
static bool is_whiteline (string s, int i) { int n= N(s); while (i<n && is_spacing (s[i])) i++; return s[i] == '\n'; }
static bool is_spacing(const char * str, t_size len) { for(t_size walk = 0; walk < len; ++walk) if (!is_spacing(str[walk])) return false; return true; }