1 // -*- C++ -*-
2 /**
3  * \file InsetMathMacro.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Alejandro Aguilar Sierra
8  * \author André Pönitz
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12 
13 #ifndef MATH_MACRO_H
14 #define MATH_MACRO_H
15 
16 #include "InsetMathNest.h"
17 #include "MacroTable.h"
18 #include "MathData.h"
19 
20 #include <map>
21 
22 namespace lyx {
23 
24 /// This class contains the data for a macro.
25 class InsetMathMacro : public InsetMathNest {
26 public:
27 	/// A macro can be built from an existing template
28 	InsetMathMacro(Buffer * buf, docstring const & name);
29 	///
30 	InsetMathMacro(InsetMathMacro const &);
31 	///
32 	InsetMathMacro & operator=(InsetMathMacro const &);
33 	///
34 	~InsetMathMacro();
35 	///
asMacro()36 	virtual InsetMathMacro * asMacro() { return this; }
37 	///
asMacro()38 	virtual InsetMathMacro const * asMacro() const { return this; }
39 	///
40 	marker_type marker(BufferView const *) const;
41 	/// If the macro is in normal edit mode, dissolve its contents in
42 	/// the row. Otherwise, just insert the inset.
43 	bool addToMathRow(MathRow &, MetricsInfo & mi) const;
44 	///
45 	void beforeMetrics() const;
46 	///
47 	void afterMetrics() const;
48 	///
49 	void beforeDraw(PainterInfo const &) const;
50 	///
51 	void afterDraw(PainterInfo const &) const;
52 
53 	///
54 	void metrics(MetricsInfo & mi, Dimension & dim) const;
55 	/// was the macro in edit mode when computing metrics?
56 	bool editMetrics(BufferView const * bv) const;
57 	///
58 	void draw(PainterInfo & pi, int x, int y) const;
59 	///
60 	int kerning(BufferView const * bv) const;
61 	/// get cursor position
62 	void cursorPos(BufferView const & bv, CursorSlice const & sl,
63 		bool boundary, int & x, int & y) const;
64 	///
65 	void edit(Cursor & cur, bool front, EntryDirection entry_from);
66 	///
67 	Inset * editXY(Cursor & cur, int x, int y);
68 
69 	/// target pos when we enter the inset while moving forward
70 	bool idxFirst(Cursor &) const;
71 	/// target pos when we enter the inset while moving backwards
72 	bool idxLast(Cursor &) const;
73 
74 	///
75 	virtual bool notifyCursorLeaves(Cursor const & old, Cursor & cur);
76 
77 	/// Remove cell (starting from 0)
78 	void removeArgument(pos_type pos);
79 	/// Insert empty cell (starting from 0)
80 	void insertArgument(pos_type pos);
81 
82 	///
83 	void validate(LaTeXFeatures &) const;
84 	///
85 	mode_type currentMode() const;
86 
87 	/// Assumes that macros are up-to-date
88 	void write(WriteStream & os) const;
89 	///
90 	void normalize(NormalStream & os) const;
91 	///
92 	void maple(MapleStream &) const;
93 	///
94 	void maxima(MaximaStream &) const;
95 	///
96 	void mathematica(MathematicaStream &) const;
97 	///
98 	void mathmlize(MathStream &) const;
99 	///
100 	void htmlize(HtmlStream &) const;
101 	///
102 	void octave(OctaveStream &) const;
103 	///
104 	void infoize(odocstream &) const;
105 	///
106 	void infoize2(odocstream &) const;
107 
108 	/// fold the macro in the next metrics call
109 	void fold(Cursor & cur);
110 	/// unfold the macro in the next metrics call
111 	void unfold(Cursor & cur);
112 	/// will it be folded or unfolded in the next metric call?
113 	bool folded() const;
114 
115 	enum DisplayMode {
116 		DISPLAY_INIT,
117 		DISPLAY_INTERACTIVE_INIT,
118 		DISPLAY_UNFOLDED,
119 		DISPLAY_NORMAL
120 	};
121 
122 	///
123 	DisplayMode displayMode() const;
124 
125 	///
126 	bool extraBraces() const;
127 
128 	///
129 	docstring name() const;
130 	/// FIXME: Often dangling.
131 	MacroData const * macro() const;
132 	///
133 	docstring macroName() const;
134 	/// Level of nesting in macros (including this one)
135 	int nesting() const;
136 	///
137 	bool validName() const;
138 	///
139 	size_t arity() const;
140 
141 	///
142 	size_t optionals() const;
143 	///
144 	void setOptionals(int n);
145 	/// Return the maximal number of arguments the macro is greedy for.
146 	size_t appetite() const;
147 	///
lyxCode()148 	InsetCode lyxCode() const { return MATH_MACRO_CODE; }
149 	/// This is not used for display; however whether it is mathrel determines
150 	/// how to split equations intelligently.
151 	MathClass mathClass() const; //override
152 	/// Override so as to set Buffer for defnition_ member, too.
153 	void setBuffer(Buffer &);
154 
155 protected:
156 	friend class MathData;
157 	friend class ArgumentProxy;
158 	friend class Cursor;
159 
160 	/// update the display mode (should only be called after detaching arguments)
161 	void setDisplayMode(DisplayMode mode, int appetite = -1);
162 	/// compute the next display mode
163 	DisplayMode computeDisplayMode() const;
164 	/// update macro definition
165 	void updateMacro(MacroContext const & mc);
166 	/// check if macro definition changed, argument changed etc. and adapt
167 	void updateRepresentation(Cursor * cur, MacroContext const & mc,
168 	                          UpdateType, int nesting);
169 	/// empty macro, put arguments into args, possibly strip arity-attachedArgsNum_ empty ones.
170 	/// Includes the optional arguments.
171 	void detachArguments(std::vector<MathData> & args, bool strip);
172 	/// attach arguments (maybe less than arity at the end of an MathData),
173 	/// including the optional ones (even if it can be empty here)
174 	void attachArguments(std::vector<MathData> const & args, size_t arity, int optionals);
175 
176 private:
177 	/// This function is needed for now because of two shortfalls of the current
178 	/// implementation: the macro() pointer is often dangling, in which case we
179 	/// fall back to a backup copy, and the macro is not known at inset
180 	/// creation, in which case we fall back to the global macro with this name.
181 	MacroData const * macroBackup() const;
182 	///
183 	virtual Inset * clone() const;
184 	///
185 	bool editMode(BufferView const * bv) const;
186 
187 	///
188 	class Private;
189 	///
190 	Private * d;
191 	/// update lock to avoid loops
192 	class UpdateLocker;
193 	friend class UpdateLocker;
194 
195 public:
196 	///
197 	bool completionSupported(Cursor const &) const;
198 	///
199 	bool inlineCompletionSupported(Cursor const & cur) const;
200 	///
201 	bool automaticInlineCompletion() const;
202 	///
203 	bool automaticPopupCompletion() const;
204 	///
205 	CompletionList const * createCompletionList(Cursor const & cur) const;
206 	///
207 	docstring completionPrefix(Cursor const & cur) const;
208 	///
209 	bool insertCompletion(Cursor & cur, docstring const & s, bool finished);
210 	///
211 	void completionPosAndDim(Cursor const &, int & x, int & y, Dimension & dim) const;
212 };
213 
214 } // namespace lyx
215 #endif
216