+ if (description == null)
+ description = (MText) "No description";
+ if (title == null)
+ title = new MText (tag[2].Name);
+ if (variables == null)
+ variables = new Variable[0];
+ if (commands == null)
+ commands = new Command[0];
+ if (! full)
+ return;
+ if (states.IsEmpty)
+ {
+ State state = new State ((MSymbol) "init");
+ plist = new MPlist ();
+ foreach (KeyValuePair<MSymbol, Map>kv in maps)
+ state.branches.Add (kv.Key, new MExpression (plist, local_domain));
+ states.Add (state.name, state);
+ }
+ }
+
+ private void load (XmlNode node, bool full)
+ {
+ bool skip_header = load_status == LoadStatus.Header;
+
+ maps = new Dictionary<MSymbol, Map> ();
+ states = new MPlist ();
+
+ if (node.NodeType == XmlNodeType.Document)
+ node = node.FirstChild;
+ while (node.NodeType != XmlNodeType.Element)
+ node = node.NextSibling;
+ for (node = node.FirstChild; node != null; node = node.NextSibling)
+ {
+ if (node.NodeType != XmlNodeType.Element)
+ continue;
+ if (! skip_header)
+ {
+ if (node.Name == "description")
+ description = parse_description (node);
+ else if (node.Name == "title")
+ title = parse_title (node);
+ else if (node.Name == "variable-list")
+ parse_variables (node);
+ else if (node.Name == "command-list")
+ parse_commands (node);
+ }
+ else if (full)
+ {
+ if (node.Name == "module-list")
+ parse_plugins (node);
+ else if (node.Name == "macro-list")
+ parse_macros (node);
+ else if (node.Name == "map-list")
+ parse_maps (node);
+ else if (node.Name == "state-list")
+ parse_states (node);
+ }
+ }
+ if (description == null)
+ description = (MText) "No description";
+ if (title == null)
+ title = new MText (tag[2].Name);
+ if (variables == null)
+ variables = new Variable[0];
+ if (commands == null)
+ commands = new Command[0];
+ if (! full)
+ return;
+ if (states.IsEmpty)
+ {
+ State state = new State ((MSymbol) "init");
+ MPlist plist = new MPlist ();
+ foreach (KeyValuePair<MSymbol, Map>kv in maps)
+ state.branches.Add (kv.Key, new MExpression (plist, local_domain));
+ states.Add (state.name, state);
+ }
+ }
+
+ private static void transform (MPlist plist)
+ {
+ for (; ! plist.IsEmpty; plist = plist.next)
+ {
+ if (plist.IsMText)
+ {
+ MPlist p = new MPlist ();
+ p.Add (MSymbol.symbol, Minsert);
+ p.Add (MSymbol.mtext, plist.Text);
+ plist.Set (MSymbol.plist, p);
+ }
+ else if (plist.IsInteger)
+ {
+ MPlist p = new MPlist ();
+ p.Add (MSymbol.symbol, Minsert);
+ p.Add (MSymbol.integer, plist.Integer);
+ plist.Set (MSymbol.plist, p);
+ }
+ else if (plist.IsPlist)
+ {
+ MPlist pl = plist.Plist;
+
+ if (pl.IsSymbol)
+ {
+ if (pl.Symbol == Madd)
+ pl.Set (MSymbol.symbol, (MSymbol) "+=");
+ else if (pl.Symbol == Msub)
+ pl.Set (MSymbol.symbol, (MSymbol) "-=");
+ else if (pl.Symbol == Mmul)
+ pl.Set (MSymbol.symbol, (MSymbol) "*=");
+ else if (pl.Symbol == Mdiv)
+ pl.Set (MSymbol.symbol, (MSymbol) "/=");
+ else if (pl.Symbol == Minsert)
+ {
+ // (insert (CANDIDATES ...))
+ // => (candidates CANDIDATES ...)
+ if (pl.next.IsPlist)
+ {
+ pl.Set (MSymbol.symbol, Mcandidates);
+ pl = pl.next;
+ MPlist p = pl.Plist;
+ pl.Set (p.key, p.val);
+ for (p = p.next; ! p.IsEmpty; p = p.next);
+ pl.Add (p.key, p.val);
+ }
+ }
+ else if (pl.Symbol == Mif)
+ {
+ pl = pl.next;
+ if (! pl.IsEmpty)
+ transform (pl.next);
+ }
+ else if (pl.Symbol == Mcond)
+ {
+ for (pl = pl.next; ! pl.IsEmpty; pl = pl.next)
+ if (pl.IsPlist)
+ {
+ MPlist p = pl.Plist;
+
+ if (p.IsPlist)
+ transform (p);
+ else
+ transform (p.next);
+ }
+ }
+ else if (pl.Symbol == Mdelete
+ || pl.Symbol == Mmove
+ || pl.Symbol == Mmark)
+ {
+ pl = pl.next;
+ if (pl.IsSymbol)
+ {
+ MSymbol sym = pl.Symbol;
+ MPlist p = new MPlist ();
+ p.Add (MSymbol.symbol, Mmarker);
+ p.Add (MSymbol.symbol, sym);
+ pl.Set (MSymbol.plist, p);
+ }
+ }
+ else if (pl.Symbol == Mpushback)
+ {
+ pl = pl.next;
+ if (pl.IsPlist)
+ pl.Plist.Push (MSymbol.symbol, Mkeyseq);
+ }
+ }
+ else if (pl.IsMText)
+ {
+ // (CANDIDATES ...) => (candidates CANDIDATES ...)
+ pl.Push (MSymbol.symbol, Mcandidates);
+ }
+ }
+ else if (plist.IsSymbol)
+ {
+ MSymbol sym = plist.Symbol;
+
+ if (sym.Name.Length >= 3
+ && sym.Name[0] == '@'
+ && (sym.Name[1] == '-' || sym.Name[1] == '+'))
+ {
+ int pos = int.Parse (sym.Name.Substring (1));
+ MPlist p = new MPlist ();
+
+ if (pos == 0)
+ {
+ p.Add (MSymbol.symbol, Msurrounding_text_p);
+ }
+ else
+ {
+ if (sym.Name[1] == '+')
+ pos--;
+ p.Add (MSymbol.symbol, Mchar_at);
+ p.Add (MSymbol.integer, pos);
+ }
+ plist.Set (MSymbol.plist, p);
+ }
+ }
+ }