--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Text.RegularExpressions;\r
+\r
+using mutil;\r
+\r
+namespace mDoc{\r
+\r
+public class Worker\r
+{\r
+ private XmlExtractor source;\r
+ private string target;\r
+ private StreamWriter outfile;\r
+ private XmlExtractor global_defs;\r
+ private XmlExtractor hierarc;\r
+ \r
+ private void print_tpl_text(Dictionary<string,string> attrs, string text) {\r
+ string rgx = @"\$\w+";\r
+ foreach (Match match in Regex.Matches(text, rgx)) {\r
+ string subst = attrs[match.Value.Substring(1)];\r
+ text = text.Replace(match.Value, subst);\r
+ }\r
+ outfile.Write(text);\r
+ }\r
+ private void process_file_layer() {\r
+\r
+ int ctl = XmlExtractor.EC_BEG;\r
+ string elem;\r
+ string doc_value;\r
+ string tpl_value;\r
+ string dummy;\r
+ Dictionary<string,string> sattrs = null;\r
+ Dictionary<string,string> tattrs = null;\r
+ object tpl_node = null;\r
+\r
+ // extract current data\r
+ source.getCurrentNodeData(out elem, out dummy, out sattrs);\r
+\r
+ // work only on copy\r
+ XmlExtractor globex = new XmlExtractor(global_defs.CurrentNode);\r
+\r
+ bool process_node = false;\r
+ bool hierarc_decend = false;\r
+ // check verbatim\r
+ if (elem == "verbatim" && sattrs["target"] == target) {\r
+ process_node = true;\r
+ // => no search for template data\r
+ }\r
+ else {\r
+ // search for template data\r
+ if (this.hierarc != null) tpl_node = this.hierarc.gotoChild(elem);\r
+ if (tpl_node != null) hierarc_decend = true;\r
+ else tpl_node = globex.gotoChild(elem);\r
+ if (tpl_node != null) process_node = true;\r
+ }\r
+ if (process_node) {\r
+ if (tpl_node != null) {\r
+ // process template pre node\r
+ XmlExtractor nodeex = new XmlExtractor(tpl_node);\r
+ object test_node = nodeex.gotoChild("pre");\r
+ if (test_node != null) {\r
+ nodeex.getCurrentNodeData(out dummy, out tpl_value, out tattrs);\r
+ print_tpl_text(sattrs, tpl_value);\r
+ nodeex.toParent();\r
+ }\r
+ }\r
+ // process source node\r
+ string child_elem;\r
+ Dictionary<string,string> cattrs = null;\r
+ ctl = source.extractElement(ctl, out child_elem, out doc_value, out cattrs);\r
+ while (ctl != XmlExtractor.EC_END) {\r
+ if (doc_value != null) {\r
+ // text_node\r
+ outfile.Write(doc_value);\r
+ } else if (child_elem != null) {\r
+ // tag node\r
+ this.process_file_layer();\r
+ } else {\r
+ throw new Exception("Neither text or tag?");\r
+ }\r
+ ctl = source.extractElement(ctl, out child_elem, out doc_value, out cattrs);\r
+ }\r
+ if (tpl_node != null) {\r
+ // process template post node\r
+ XmlExtractor nodeex = new XmlExtractor(tpl_node);\r
+ object test_node = nodeex.gotoChild("post");\r
+ if (test_node != null) {\r
+ nodeex.getCurrentNodeData(out dummy, out tpl_value, out tattrs);\r
+ print_tpl_text(sattrs, tpl_value);\r
+ nodeex.toParent();\r
+ }\r
+ }\r
+ if (hierarc_decend) hierarc.toParent();\r
+ outfile.WriteLine();\r
+ } else {\r
+ Console.WriteLine("No template entry for node: "+elem);\r
+ }\r
+ }\r
+\r
+/*\r
+\r
+ print_tpl_text(tpl_node, "pre");\r
+\r
+\r
+\r
+ // 2) chech for leading texts\r
+ process_definitions(elem, value, attrs, global_defs, Leading: true);\r
+ process_definitions(elem, value, attrs, hierarc, Leading: true);\r
+ }\r
+ \r
+\r
+\r
+ // so gehts nicht, die items können mehrfach vorkommen!\r
+\r
+ // check for hierarchical definition\r
+ object items = hiraex.gotoChild(elem);\r
+ if (items == null) {\r
+ // check for any global definition\r
+ items = globex.gotoChild(elem);\r
+ }\r
+ if (items != null) {\r
+ XmlExtractor itemex = new XmlExtractor(items, TextMode: true);\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+\r
+\r
+ # search for "first"\r
+ for item in items:\r
+ if "position" in item["attrs"]:\r
+ if item["attrs"]["position"] == "first":\r
+ print (item["value"], end="", file=outfile)\r
+ # proceed working\r
+ for item in items:\r
+ if not "position" in item["attrs"]:\r
+ # determine line end\r
+ end = "\n"\r
+ if "end" in item["attrs"]:\r
+ end = item["attrs"]["end"]\r
+ # check "pre"\r
+ if "pre" in item["attrs"]:\r
+ text = item["attrs"]["pre"]\r
+ if text.startswith(r"\n"):\r
+ print (file=outfile)\r
+ text = text[2:]\r
+ print (text, end="", file=outfile)\r
+ if "exec" in item["attrs"]:\r
+ # call function\r
+ store_current_node = source.currentNode\r
+ l = {"out" : None, "source":source}\r
+ exec(functions[item["attrs"]["exec"]], globals(), l)\r
+ # proceed on previous position\r
+ source.currentNode = store_current_node\r
+ print (l["out"], file=outfile)\r
+ else:\r
+ # proceed working\r
+ nexthiera = item["items"]\r
+ if value:\r
+ print (value, end="", file=outfile)\r
+ process_file_layer(source, outfile, global_defs, nexthiera, functions, target)\r
+ # check "post"\r
+ if "post" in item["attrs"]:\r
+ print (item["attrs"]["post"], end="", file=outfile)\r
+ print (end=end, file=outfile)\r
+ # search for "last"\r
+ for item in items:\r
+ if "position" in item["attrs"]:\r
+ if item["attrs"]["position"] == "last":\r
+ print (item["value"], end="", file=outfile)\r
+\r
+ (ctl,elem, value, attrs) = source.extractElement(ctl)\r
+*/\r
+ public int convert(string file, string tpl_file) {\r
+ \r
+ // open xml document\r
+ source = new XmlExtractor(TextMode: true);\r
+ source.openInput(file);\r
+\r
+ // goto root element\r
+ string elem;\r
+ string value;\r
+ Dictionary<string,string> attrs;\r
+ source.extractElement(XmlExtractor.EC_BEG, out elem, out value, out attrs);\r
+\r
+ // open template\r
+ XmlExtractor tple = new XmlExtractor(TextMode: true);\r
+ tple.openInput(tpl_file);\r
+ /*\r
+ functions_in_file = tpl["mdoc"][0]["items"]["functions"][0]["items"]["function"];\r
+ // compile functions\r
+ var functions = new Dictionary<string,string>();\r
+ for f in functions_in_file:\r
+ name = f["attrs"]["name"]\r
+ functions[name] = compile(f["value"], '<string>', "exec")\r
+ */\r
+ \r
+ tple.requireChild("mdoc");\r
+ tple.getCurrentNodeData(out elem, out value, out attrs);\r
+ string ext = attrs["extension"];\r
+\r
+ int cntl = XmlExtractor.EC_BEG;\r
+\r
+ cntl = tple.extractElement(cntl, out elem, out value, out attrs);\r
+ while (cntl != XmlExtractor.EC_END) {\r
+ if (elem == "global") this.global_defs = new XmlExtractor(tple.CurrentNode, TextMode: true);\r
+ else if (elem == "hierarchical") this.hierarc = new XmlExtractor(tple.CurrentNode, TextMode: true);\r
+ cntl = tple.extractElement(cntl, out elem, out value, out attrs);\r
+ }\r
+ \r
+ // open output file\r
+ //outname = re.sub(r"\.xml", "."+ext, file)\r
+ string outname = file.Substring(0,file.IndexOf(".")+1) + ext;\r
+ using ( outfile = new StreamWriter (outname)) {\r
+ process_file_layer();\r
+ }\r
+ return 0;\r
+ }\r
+}\r
+\r
+}\r
+\r
+/*\r
+from mutil.XmlExtractor import XmlExtractor\r
+from mutil import XmlExtractor as XMLE\r
+import re\r
+'''\r
+def outfirst(outfile, tpllayer, attrs, value):\r
+ if tpllayer["value"]:\r
+ ostr = tpllayer["value"]\r
+ if "$value" in ostr:\r
+ ostr = re.sub(r"\$value", value, ostr, flags=re.MULTILINE)\r
+ print (ostr, end="", file=outfile)\r
+\r
+def outlast(outfile, tpllayer, attrs, value):\r
+ if tpllayer["value"]:\r
+ print (file=outfile)\r
+'''\r
+ \r
+*/\r
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace mutil {
+
+public class XmlExtractor {
+ public const int EC_BEG = 1; // begin of subtree (current node descends) - in
+ public const int EC_CTN = 2; // continue with next sibling element - in / out: data of found element
+ public const int EC_END = 3; // subtree completion (current node ascends); no data - out
+
+
+ private XmlDocument docNode;
+ private bool textMode;
+ public XmlNode CurrentNode;
+
+ public XmlExtractor(object BaseNode = null, bool TextMode = false) {
+ this.CurrentNode = (XmlNode)BaseNode;
+ this.textMode = TextMode;
+ }
+
+ public void openInput(string input){
+ this.docNode = new XmlDocument();
+ this.docNode.Load(input);
+ this.CurrentNode = this.docNode;
+ }
+
+ public void toTop(){
+ this.CurrentNode = this.docNode;
+ }
+ public void toParent(){
+ this.CurrentNode = this.CurrentNode.ParentNode;
+ }
+ public int extractElement(int extr_ctl, out string elem, out string value, out Dictionary<string,string> attrs) {
+ elem = "";
+ value = null;
+ attrs = new Dictionary<string,string>();
+
+ XmlNode srh_node;
+
+ if (extr_ctl == EC_BEG) {
+ srh_node = this.CurrentNode.FirstChild;
+ } else if (extr_ctl == EC_CTN) {
+ srh_node = this.CurrentNode.NextSibling;
+ } else {
+ return EC_END;
+ }
+
+ // search for next element node
+ if (! this.textMode) {
+ while (srh_node != null) {
+ if (srh_node.NodeType != XmlNodeType.Element) {
+ srh_node = srh_node.NextSibling;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (srh_node != null) {
+ // element node found: extract tag name, value and attributes
+ this.CurrentNode = srh_node;
+ this.getCurrentNodeData(out elem, out value, out attrs);
+ return EC_CTN;
+ } else {
+ // terminate / ascend subtree after child extraction
+ if (extr_ctl == EC_CTN) {
+ this.CurrentNode = this.CurrentNode.ParentNode;
+ }
+ return EC_END;
+ }
+
+ }
+ public void getCurrentNodeData(out string elem, out string value, out Dictionary<string,string> attrs) {
+ elem = this.CurrentNode.Name;
+ value = null;
+ attrs = new Dictionary<string,string>();
+ if (this.textMode) {
+ if (this.CurrentNode.NodeType == XmlNodeType.Text) value = this.CurrentNode.Value;
+ }
+ else {
+ if (this.CurrentNode.InnerText != null) value = this.CurrentNode.InnerText;
+ }
+ if (this.CurrentNode.Attributes != null) {
+ for (int att_idx = 0; att_idx < this.CurrentNode.Attributes.Count; att_idx++) {
+ var att_node = this.CurrentNode.Attributes[att_idx];
+ attrs[att_node.Name] = this.CurrentNode.Attributes[att_idx].Value;
+ }
+ }
+ }
+ public XmlNode gotoChild(string name) {
+ // return True/False, if child node could be found
+ int cntl = EC_BEG;
+ string elem;
+ string value;
+ Dictionary<string,string> attrs;
+ while ((cntl = this.extractElement(cntl, out elem, out value, out attrs)) != EC_END) {
+ if (elem == name) return this.CurrentNode;
+ }
+ return null;
+ }
+ public XmlNode requireChild(string name) {
+ // throws exception, if child not present
+ XmlNode child = this.gotoChild(name);
+ if (child == null) throw new Exception("Could not find node "+name);
+ return child;
+ }
+}
+}