1 
2 #pragma once
3 
4 #include "DisplayBase.hh"
5 #include <ostream>
6 #include <map>
7 #include <set>
8 
9 typedef uint32_t kunichar;
10 
11 namespace cadabra {
12 
13 	/// \ingroup display
14 	///
15 	/// Class to display expressions in a format that Mathematica can
16 	/// parse. Will throw an exception if a Cadabra Ex object cannot be
17 	/// understood by Mathematica. Can also convert expressions back to
18 	/// Cadabra notation.
19 
20 	class DisplayMMA : public DisplayBase {
21 		public:
22 			DisplayMMA(const Kernel&, const Ex&, bool use_unicode);
23 
24 			/// Rewrite the output of mathematica back into a notation used by
25 			/// Cadabra. This in particular involves converting 'Sin' and
26 			/// friends to `\sin` and so on, as well as converting all the
27 			/// greek symbols.  Currently only acts node-by-node, does not
28 			/// do anything complicated with trees.
29 
30 			void import(Ex&);
31 
32 			std::string preparse_import(const std::string&);
33 
34 		protected:
35 			bool use_unicode;
36 
37 			virtual bool needs_brackets(Ex::iterator it) override;
38 
39 		private:
40 			/// Output the expression to a mathematica-readable form. For symbols
41 			/// which cannot be parsed by mathematica, this can convert to an
42 			/// alternative, Such rewrites can then be undone by the
43 			/// 'import' member above.
44 
45 			void print_multiplier(std::ostream&, Ex::iterator);
46 			void print_opening_bracket(std::ostream&, str_node::bracket_t);
47 			void print_closing_bracket(std::ostream&, str_node::bracket_t);
48 			void print_parent_rel(std::ostream&, str_node::parent_rel_t, bool first);
49 			void print_children(std::ostream&, Ex::iterator, int skip=0);
50 
51 
52 			/// For every object encountered, dispatch will figure out the
53 			/// most appropriate way to convert it into a LaTeX
54 			/// expression. This may be done by simply looking at the
55 			/// object's name (e.g. `\prod` will print as a product) but may
56 			/// also involve looking up properties and deciding on the best
57 			/// course of action based on the attached properties.
58 
59 			virtual void dispatch(std::ostream&, Ex::iterator) override;
60 
61 			/// Printing members for various standard constructions,
62 			/// e.g. print as a list, or as a decorated symbol with
63 			/// super/subscripts etc. The names reflect the structure of the
64 			/// output, not necessarily the meaning or name of the object
65 			/// that is being printed.
66 
67 			void print_productlike(std::ostream&, Ex::iterator, const std::string& inbetween);
68 			void print_sumlike(std::ostream&, Ex::iterator);
69 			void print_fraclike(std::ostream&, Ex::iterator);
70 			void print_commalike(std::ostream&, Ex::iterator);
71 			void print_arrowlike(std::ostream&, Ex::iterator);
72 			void print_powlike(std::ostream&, Ex::iterator);
73 			void print_intlike(std::ostream&, Ex::iterator);
74 			void print_equalitylike(std::ostream&, Ex::iterator);
75 			void print_components(std::ostream&, Ex::iterator);
76 			void print_partial(std::ostream& str, Ex::iterator it);
77 			void print_matrix(std::ostream& str, Ex::iterator it);
78 			void print_other(std::ostream& str, Ex::iterator it);
79 
80 			bool children_have_brackets(Ex::iterator ch) const;
81 
82 			/// Map from Cadabra symbols to Mathematica symbols.
83 			/// This is a bit tricky because MathLink does not pass
84 			/// `\[Alpha]` and friends transparently. So we feed it UTF8
85 			/// α and so on, but then we get `\[Alpha]` back, and that
86 			/// needs to be regex-replaced before we feed it to our
87 			/// parser as ours does not swallow that kind of bracketing.
88 			std::map<std::string, std::string>      symmap;
89 			std::multimap<std::string, std::string> regex_map;
90 
91 			/// Map from symbols which have had dependencies added
92 			/// to an expression containing these dependencies.
93 			std::map<nset_t::iterator, Ex, nset_it_less> depsyms;
94 		};
95 
96 	const char *unichar(kunichar c);
97 
98 	}
99