diff --git a/TeXmacs/packages/environment/env-program.ts b/TeXmacs/packages/environment/env-program.ts index 9234b7ef16..b418d35472 100644 --- a/TeXmacs/packages/environment/env-program.ts +++ b/TeXmacs/packages/environment/env-program.ts @@ -214,6 +214,8 @@ > > + + <\active*> <\src-comment> diff --git a/TeXmacs/tests/tmu/66_8_prog.tmu b/TeXmacs/tests/tmu/66_8_prog.tmu new file mode 100644 index 0000000000..617a73014a --- /dev/null +++ b/TeXmacs/tests/tmu/66_8_prog.tmu @@ -0,0 +1,28 @@ +> + +> + +<\body> + 开始 + + <\python-code> +import os +def less(a, b): + return a <= b + + + 结束 + + +<\initial> + <\collection> + + + + + +<\references> + <\collection> + > + + \ No newline at end of file diff --git a/src/Data/Convert/Mogan/from_tmu.cpp b/src/Data/Convert/Mogan/from_tmu.cpp index 530a85bf34..6d1e208314 100644 --- a/src/Data/Convert/Mogan/from_tmu.cpp +++ b/src/Data/Convert/Mogan/from_tmu.cpp @@ -50,6 +50,7 @@ struct tmu_reader { string read_char (); string read_next (); string read_function_name (); + string read_prog_line (); tree read_apply (string s, bool skip_flag); tree read (bool skip_flag); }; @@ -176,6 +177,16 @@ tmu_reader::read_function_name () { return name; } +string +tmu_reader::read_prog_line () { + int old_pos= pos; + int buf_N = N (buf); + while (((pos + 1) < buf_N) && (buf[pos] != '\n')) { + pos++; + } + return buf (old_pos, pos); +} + static void get_collection (tree& u, tree t) { if (is_func (t, COLLECTION) || is_func (t, DOCUMENT) || is_func (t, CONCAT)) { @@ -196,18 +207,36 @@ tmu_reader::read_apply (string name, bool skip_flag) { t= tree ((tree_label) codes[name]); } - bool closed= !skip_flag; - int buf_N = N (buf); - while (pos < buf_N) { - // cout << "last= " << last << LF; - bool sub_flag= (skip_flag) && ((last == "") || (last[N (last) - 1] != '|')); - if (sub_flag) (void) skip_blank (); - t << read (sub_flag); - if ((last == "/>") || (last == "/|")) closed= true; - if (closed && ((last == ">") || (last == "/>"))) break; + int buf_N= N (buf); + if (is_tree_in_prog (t)) { + tree D (DOCUMENT); + while (pos < buf_N) { + string line= read_prog_line (); + if (is_empty (line)) { + pos++; + continue; + } + if (ends (line, "")) { + break; + } + D << line; + } + t << D; + } + else { + bool closed= !skip_flag; + while (pos < buf_N) { + // cout << "last= " << last << LF; + bool sub_flag= + (skip_flag) && ((last == "") || (last[N (last) - 1] != '|')); + if (sub_flag) (void) skip_blank (); + t << read (sub_flag); + if ((last == "/>") || (last == "/|")) closed= true; + if (closed && ((last == ">") || (last == "/>"))) break; + } + // cout << "last= " << last << UNINDENT << LF; + // cout << "Done" << LF; } - // cout << "last= " << last << UNINDENT << LF; - // cout << "Done" << LF; if (is_func (t, COLLECTION)) { tree u (COLLECTION); diff --git a/src/Data/Convert/Mogan/to_tmu.cpp b/src/Data/Convert/Mogan/to_tmu.cpp index ae5adc6969..4b3609408c 100644 --- a/src/Data/Convert/Mogan/to_tmu.cpp +++ b/src/Data/Convert/Mogan/to_tmu.cpp @@ -47,6 +47,7 @@ struct tmu_writer { void br (int indent= 0); void tag (string before, string s, string after); void apply (string func, array args); + void write_prog (tree t); void write (tree t); }; @@ -208,6 +209,38 @@ tmu_writer::apply (string func, array args) { } } +void +tmu_writer::write_prog (tree t) { + string func= as_string (L (t)); + + // <\python-code> + write ("<\\", false); + write (func, true, true); + write (">", false); + write ("\n", false); + + tree doc = t[0]; + int doc_N= N (doc); + for (int i= 0; i < doc_N; i++) { + if (is_atomic (doc[i])) { + write (tree_to_verbatim (doc[i]->label), false); + } + else { + write (doc[i]); + } + write ("\n", false); + } + + // __ + // _ means spaces, the number is controlled by tab + for (int i= 0; i < tab; i++) { + write (" ", false); + } + write ("", false); +} + void tmu_writer::write (tree t) { if (is_atomic (t)) { @@ -265,7 +298,12 @@ tmu_writer::write (tree t) { tag (""); break; default: - apply (as_string (L (t)), A (t)); + if (is_tree_in_prog (t) && N (t) == 1 && L (t[0]) == moebius::DOCUMENT) { + write_prog (t); + } + else { + apply (as_string (L (t)), A (t)); + } break; } } diff --git a/src/Data/Convert/convert.hpp b/src/Data/Convert/convert.hpp index 5e3db2c3b9..3b85bceebf 100644 --- a/src/Data/Convert/convert.hpp +++ b/src/Data/Convert/convert.hpp @@ -14,7 +14,9 @@ #include "analyze.hpp" #include "hashmap.hpp" #include "tree.hpp" +#include "tree_helper.hpp" #include "url.hpp" +#include class object; @@ -54,6 +56,11 @@ tree eqnumber_to_nonumber (tree t); string search_metadata (tree doc, string kind); /*** TMU ***/ +inline bool +is_tree_in_prog (tree t) { + return moebius::drd::the_drd->get_attribute (L (t), "prog") == "true"; +} + tree tmu_to_tree (string s); tree tmu_document_to_tree (string s); string tree_to_tmu (tree t); diff --git a/src/Typeset/Env/env_exec.cpp b/src/Typeset/Env/env_exec.cpp index a16d9bdd5a..7f54c995b1 100644 --- a/src/Typeset/Env/env_exec.cpp +++ b/src/Typeset/Env/env_exec.cpp @@ -742,6 +742,9 @@ edit_env_rep::exec_drd_props (tree t) { else if (prop == "name") { if (is_atomic (val)) drd->set_attribute (l, prop, val->label); } + else if (prop == "prog") { + if (is_atomic (val)) drd->set_attribute (l, prop, val->label); + } else if (prop == "syntax") drd->set_syntax (l, val); else if (prop == "border") { if (val == "yes") drd->set_border (l, BORDER_YES);