1 #LyX 1.5.2 created this file. For more info see http://www.lyx.org/
10 \font_typewriter default
11 \font_default_family default
17 \paperfontsize default
24 \paperorientation portrait
27 \paragraph_separation indent
29 \quotes_language english
32 \paperpagestyle default
33 \tracking_changes false
42 Dynamic Macros for LyX
49 \begin_inset LatexCommand url
50 target "sts@1stein.org"
65 \begin_layout Standard
66 LyX has the concept of math macros for quite some time.
67 In LyX 1.4 or 1.5 you can create one in your document by calling the
71 command in the mini buffer.
72 Visually this results in something equivalent to a TeX macro:
77 \begin_layout Standard
93 \begin_layout Standard
94 After LyX processed this, the command is available in math environments
95 in the same documents.
96 But internally there is nothing more than
101 The position inside the document does not matter.
102 The command is available even in front of the definition.
103 But even worse, this global macro table is global for all opened documents.
104 If two buffers use the same macro name with different definitions, you
106 The behaviour is undefined.
107 If you are lucky LyX will not crash.
108 Nothing must be said about redefining a macro later in the document: the
109 behaviour of LyX will not be what you expect.
112 \begin_layout Standard
113 LyX 1.4 and 1.5 do not show the support for this kind of macro very prominently.
114 In fact it is described in the
115 \begin_inset Quotes eld
119 \begin_inset Quotes erd
123 But there is no menu item to create macros.
124 Next to the mentioned method with the mini buffer you can use the
125 \begin_inset Quotes eld
129 \begin_inset Quotes erd
132 short cut to convert a raw
134 newcommand into a LyX math macro.
135 Hence the role of macro is more of a power user tool for users who know
139 \begin_layout Section
140 A wish list for a new macro implementation
143 \begin_layout Standard
144 In the following usecases are shown which can be wished to be supported
145 if macros are reimplemented.
146 Most of them are not possible in the old implemention, or at least very
151 \begin_layout Enumerate
156 with a known arity ("arity" = number of arguments).
157 Use instances later on in the document.
160 \begin_layout Enumerate
165 a macro to use the same macro name with different definitions in different
166 areas of the document.
169 \begin_layout Enumerate
176 in the preamble (i.e.
177 by importing tex code) or
181 as a LyX macro in another way, and then define the command as a native
182 LyX math macro later.
183 All the uses of the old command should then turn into instances of the
188 \begin_layout Enumerate
193 a macro and also adapt all the instance of the macro in the document.
196 \begin_layout Enumerate
201 of a macro (normaly probably increase it), maybe with a default value used
202 in instances of the macro (possibly empty).
205 \begin_layout Enumerate
213 \begin_layout Enumerate
214 Insertion of a macro via the
218 like "Insert->MathMacro".
221 \begin_layout Enumerate
229 \begin_layout Enumerate
232 \begin_inset LatexCommand label
239 Editing of a macro instance as a
243 of #1: __, #2: __, i.e.
248 s when the cursor goes inside.
251 \begin_layout Enumerate
256 (the macro definition will be read-only, only the arguments as holes are
260 \begin_layout Enumerate
268 \begin_inset LatexCommand ref
269 reference "sub:listedit"
275 for certain macros, not only globally.
278 \begin_layout Enumerate
281 macros inside of macros
286 \begin_layout Enumerate
287 Using macros with the
291 , but different definitions in different open documents or parts of the
295 \begin_layout Enumerate
296 Using macros from the
303 \begin_layout Enumerate
304 Using the same argument, e.g.
309 ) more than once in the definition, like
318 \begin_layout Enumerate
334 \begin_layout Enumerate
339 substitution (or call-by-name text substition) like
347 , which is applicable like
360 \begin_layout Enumerate
374 \begin_layout Standard
375 The old implementation supports the following:
396 Though support of master documents is more or less an coincidence by the
400 \begin_layout Standard
401 The implementation described later (short: the new implementation) supports
457 \begin_layout Standard
468 macros inside of macros
483 The last 3 should be doable without much work, maybe also
490 \begin_layout Subsection
491 Main deficiencies of the old system
494 \begin_layout Standard
495 The main problem of the old implementation is that it is not dynamic at
497 A macro is resolved (i.e.
498 the lookup in the global table takes place) when the internal object is
504 document or when typing
511 If no macro definition of the right name exists at this time, an ERT is
516 \begin_layout Standard
517 Moreover there is no position awareness of the definition, only during loading
518 of a document there is something like that because macro definitions are
519 put into the global table at the point in the document where it appears.
523 \begin_layout Section
527 \begin_layout Standard
528 The goal of a new macro approach must be to support as many use cases subsection
529 1.2 as possible, or at least make an implementation possible of the remaining
531 Moreover a proper implementation better brings most of TeX's power of math
535 \begin_layout Standard
536 In a few words the new approach could be described as follow:
539 \begin_layout Itemize
540 A macro is a dynamic inset which can
541 \begin_inset Quotes eld
545 \begin_inset Quotes erd
549 \begin_inset Quotes eld
553 \begin_inset Quotes erd
556 insets which follow the macro, depending on the success to resolve it and
557 the arity of the macro definition at the position in the document.
560 \begin_layout Itemize
561 Macros are resolved again everytime it is redrawn on screen if the macro
562 definition changed which is valid at the position.
565 \begin_layout Standard
567 \begin_inset Quotes eld
571 \begin_inset Quotes erd
575 \begin_inset Quotes eld
579 \begin_inset Quotes erd
582 process is the key idea.
583 Imagine a macro definition
591 which is valid when a macro
597 appears in the context
604 When the macro is drawn the definition is checked and the arity is compared
606 \begin_inset Quotes eld
610 \begin_inset Quotes erd
614 At the beginning the latter will be zero.
621 is 2, the macro inset will eat up 2 insets (the
629 ), hence internally the macro
635 is changed to arity 2 and
644 The visual representation of macro is that of the definition with the arguments
645 replaced by the eaten insets.
646 So eventually you will see
653 \begin_layout Standard
654 When you change the macro definition at the position into a unary macro,
664 , the macro inset will spit out the second eaten inset, here the
669 Hence you will eventually see
676 \begin_layout Standard
677 This process is done automatically, transparent to the user and in a fast
678 way everytime the macro is rendered and the definition has changed.
681 \begin_layout Standard
682 If you look at the produced TeX code of the
688 you will notice that it didn't change during all this eating and spitting.
689 This is what you expect from a macro in TeX.
690 There the whole sense of command (i.e.
691 macros) is that you keep the same TeX code, independently from the macro
693 This approach carries this over to the LyX world.
696 \begin_layout Subsection
700 \begin_layout Subsubsection
704 \begin_layout Standard
705 When a MathData object is drawn, more precisely when the metrics are computed,
706 all math macros in the
710 are processed in the way described in the previous section.
711 If the arity of definition of a macro is changed the spitting/eating process
713 This is implemented in
715 MathData::updateMacros
717 , in a quite straight forward way.
721 \begin_layout Standard
722 Some complexity comes into the game by the necessary updating of the current
724 If the user unfolds a macro the arity practically changes to zero, hence
725 the arguments are spit out.
726 If the cursor was inside an argument before, it should be in the same argument
728 The same should be the case for folding.
731 \begin_layout Standard
732 The metrics calculation is, by its typing, a const method, i.e.
733 it shouldn't change the
738 The macro updating though does changes of course.
739 Technically this is true, semantically (taking the produced TeX code as
740 semantics) it is not because nothing changes by eating/spitting or folding/unfo
741 lding with the later output.
742 To still allow these changes in
751 This is somewhat ugly and a cleaner solution should be found.
752 Maybe one day the drawing and metrics will merge, then it would make sense
760 \begin_layout Subsubsection
764 \begin_layout Standard
769 know which macro definitions are known at its position in the buffer? During
774 is passed around as an element of the
779 This context can be asked to resolve a macro name.
782 \begin_layout Standard
783 To make this possible it has to know about a position in the buffer.
784 In fact it knows about the paragraph in the buffer, and in addition it
786 \begin_inset Quotes eld
790 \begin_inset Quotes erd
798 The latter is used to also resolve macros correctly which are defined in
799 the paragraph where the macro appears.
800 The inset loop in the
802 TextMetrics::redoParagraph
804 creates and updates the
808 and the local macros in the expected way.
812 \begin_layout Standard
813 All the other macros are resolved by the
817 by asking the buffer directly.
822 , as written above, knows the paragraph it belongs to.
823 It passes this information to the buffer (via
825 Buffer::hasMacro(docstring name, Paragraph par)
827 ) and the buffer then uses the
829 par.macrocontextPosition()
831 information to lookup the defined macros at the position in the map
833 Buffer::pimpl->macros
836 This maps macro names and positions to the macro definitions.
837 which are defined at the position or before.
840 \begin_layout Standard
841 The missing bit is how the buffer creates this map.
842 This is done in the same way as in the old macro implementation, namely
843 by the Buffer::updateMacros method which iterates over the top-level inset
847 BufferView::processUpdateFlags
850 This sounds slow, but it turned out that it is not noticable in fact.
851 In LyX 1.5 the same is done as well already.
852 Maybe some optimisation could help though, but was not investigated.
855 \begin_layout Standard
856 To support master documents there will a last lookup (if the previous lookup
857 were not successfull) by asking the master buffer.
860 \begin_layout Subsection
864 \begin_layout Standard
865 The file format concerning macros in the old macro implementation is not
867 As described above there is a big difference between the visual semantics
868 (what the user sees inside LyX 1.5) and the latex semantics (what LaTeX
869 will make out of the document) are not the same.
872 \begin_layout Standard
873 The new approach changes this for most documents (if the user does not do
874 any dirty tricks at least) to be the same.
875 So from the file format point of view there probably should not be any
876 conversion needed to a new file format.
879 \begin_layout Standard
880 One exception of this comes from the support for optional arguments in the
882 Those were not available in the old format.
885 \begin_layout Subsubsection
889 \begin_layout Standard
890 Macro definitions are stored in the following way:
891 \begin_inset listings
895 \begin_layout Standard
899 begin_inset FormulaMacro
902 \begin_layout Standard
919 \begin_layout Standard
931 \begin_layout Standard
932 The resulting LaTeX code is as expected:
933 \begin_inset listings
937 \begin_layout Standard
959 \begin_layout Subsubsection
960 One Optional Argument
963 \begin_layout Standard
964 With one optional argument the LyX code looks like this:
965 \begin_inset listings
969 \begin_layout Standard
973 begin_inset FormulaMacro
976 \begin_layout Standard
993 \begin_layout Standard
1002 and the LaTeX code again is the same:
1003 \begin_inset listings
1007 \begin_layout Standard
1029 \begin_layout Subsubsection
1030 Multi Optional Argument Macro
1033 \begin_layout Standard
1034 More than one optional argument is not supported by LaTeX.
1035 There are several solutions to allow them by defining some custom
1041 , but this is not standarized.
1042 It might make sense for LyX to also support those when importing, but this
1044 Instead the new implementation will create valid standard LaTeX code by
1045 outputting what the user sees on screen in LyX:
1046 \begin_inset listings
1050 \begin_layout Standard
1054 begin_inset FormulaMacro
1057 \begin_layout Standard
1076 \begin_layout Standard
1085 with the LaTeX code:
1086 \begin_inset listings
1090 \begin_layout Standard
1111 When the user creates an instance of
1113 xyz without substituting the optional argument, e.g.
1115 \begin_inset listings
1119 \begin_layout Standard
1128 LyX will create the following LaTeX code when exporting to LaTeX:
1129 \begin_inset listings
1133 \begin_layout Standard
1142 So the optional argument is not optional anymore after export, but explicit.
1145 \begin_layout Subsubsection
1151 \begin_layout Standard
1152 Last but not least, as in the old implementation you can use
1159 TeX style definitions.
1160 They don't support optional arguments.
1162 \begin_inset Quotes eld
1166 \begin_inset Quotes erd
1177 where you can use it as in
1186 \begin_layout Subsubsection
1190 \begin_layout Standard
1191 On export LyX will correctly use
1204 This is not visible in the LyX file format though.
1207 \begin_layout Subsection
1208 How it looks to the user
1211 \begin_layout Subsubsection
1215 \begin_layout Standard
1216 Macro definitions look more or less the same as in the old implementation.
1218 there is a macro definition inset showing the macro like
1230 \begin_inset Quotes eld
1234 \begin_inset Quotes erd
1246 \begin_layout Standard
1247 A second way to create them is to write down the LaTeX definition like
1256 Select it and press Ctrl-m.
1259 \begin_layout Standard
1260 The last way, which is new with the new implementation, is to use the Insert/Mat
1264 \begin_layout Subsubsection
1268 \begin_layout Standard
1269 The are the following actions defined:
1272 \begin_layout Standard
1273 \begin_inset Tabular
1274 <lyxtabular version="3" rows="12" columns="2">
1276 <column alignment="center" valignment="top" leftline="true" width="0">
1277 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
1278 <row topline="true" bottomline="true">
1279 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1282 \begin_layout Standard
1288 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1291 \begin_layout Standard
1298 <row topline="true">
1299 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1302 \begin_layout Standard
1308 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1311 \begin_layout Standard
1312 View/Unfold Math Macro
1318 <row topline="true">
1319 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1322 \begin_layout Standard
1328 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1331 \begin_layout Standard
1332 View/Fold Math Macro
1338 <row topline="true">
1339 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1342 \begin_layout Standard
1343 math-macro-add-param
1348 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1351 \begin_layout Standard
1352 Edit/Math/Macro/Append Parameter
1358 <row topline="true">
1359 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1362 \begin_layout Standard
1363 math-macro-remove-param
1368 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1371 \begin_layout Standard
1372 Edit/Math/Macro/Remove Last Parameter
1378 <row topline="true">
1379 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1382 \begin_layout Standard
1383 math-macro-append-greedy-param
1388 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1391 \begin_layout Standard
1392 Edit/Math/Macro/Append Parameter Eating From the Right
1398 <row topline="true">
1399 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1402 \begin_layout Standard
1403 math-macro-make-optional
1408 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1411 \begin_layout Standard
1412 Edit/Math/Macro/Make First Non-Optional into Optional Parameter
1418 <row topline="true">
1419 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1422 \begin_layout Standard
1423 math-macro-remove-greedy-param
1428 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1431 \begin_layout Standard
1432 Edit/Math/Macro/Remove Last Parameter Spitting Out To The Right
1438 <row topline="true">
1439 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1442 \begin_layout Standard
1443 math-macro-make-nonoptional
1448 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1451 \begin_layout Standard
1452 Edit/Math/Macro/Make Last Optional into Non-Optional Parameter
1458 <row topline="true">
1459 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1462 \begin_layout Standard
1463 math-macro-add-optional-param
1468 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1471 \begin_layout Standard
1472 Edit/Math/Macro/Insert Optional Parameter
1478 <row topline="true">
1479 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1482 \begin_layout Standard
1483 math-macro-remove-optional-param
1488 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1491 \begin_layout Standard
1492 Edit/Math/Macro/Remove Optional Parameter
1498 <row topline="true" bottomline="true">
1499 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1502 \begin_layout Standard
1503 math-macro-add-greedy-optional-param
1508 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1511 \begin_layout Standard
1512 Edit/Math/Macro/Append Optional Parameter Eating From the Right
1525 \begin_layout Subsubsection
1530 \begin_layout Standard
1531 As described above the key idea is that macros and eat up and spit out parameter
1532 s, depending on their arity.
1533 This makes them very dynamic and powerful, but at the same time adds some
1534 complexity which must be understood by the user to effectively use the
1538 \begin_layout Standard
1539 Hence if the arity is increased (i.e.
1540 another parameter is added to a macro) there are two ways to do that: if
1541 this is done greedily the macro tries to eat up another inset from the
1543 This is the natural way if you import a document and then start to define
1544 a macros with LyX's math macros.
1545 Then you want that the macros take the (existing) paramenters from the
1549 \begin_layout Standard
1550 The second case is the non-greedy use case.
1552 you want to change a macro to take another parameter because you just found
1553 out that your notation needs another index.
1554 Then you want to insert this non-greedily.
1555 All macro instances in your text should get another parameter without touching
1559 \begin_layout Standard
1560 The greedy variants of the actions have the word
1561 \begin_inset Quotes eld
1565 \begin_inset Quotes erd
1571 \begin_layout Standard
1572 Some of the actions also take a paramenter to define the position to act
1573 on in the parameter list.
1577 math-macro-add-param 2
1579 in the mini-buffer to add a parameter at position 2.
1582 \begin_layout Subsubsection
1586 \begin_layout Standard
1587 Sometimes it is desireable to switch to the TeX code of a macro instance,
1589 without any substitution using the macro definition.
1590 This can be done with the fold/unfold actions.
1602 \begin_layout Standard
1603 If you nest macro instances these actions will unfold from inside to the
1604 outside and the same for folding.
1605 This is supposed to replace the old list display when entering a macro.
1608 \begin_layout Subsubsection
1612 \begin_layout Standard
1613 Currently there is no toolbar for math macros.
1614 Because the menu hierarchy is very deep a toolbar would make the life a
1616 It shouldn't be hard to implement that.
1619 \begin_layout Subsubsection
1620 More natural macro definition editing
1623 \begin_layout Standard
1624 Instead of the described actions it would desirable to add another more
1625 natural way to edit macros.
1626 The vision is that the user can put the cursor everywhere inside of the
1627 macro definition inset which shows (already now!) the definition in the
1632 name{#1}{#2}:={definition}
1635 The user should be able to use the backspace and the
1639 key to remove and add parameters when the cursor is in the parameter definition
1641 For a non-greedy macro-append one could put a small (+) button or a hungry
1650 in front of the definition.
1653 \begin_layout Standard
1654 For implementing this one has to customize the
1658 a lot to handle the keypresses correctly, because it's probably not directly
1663 in a simple way with its children insets.
1666 \begin_layout Subsubsection
1670 \begin_layout Standard
1679 with the cursor key and conversely backwards.
1680 This navigation is not visual.
1682 the user can define macros like
1686 foo{#1}{#2}:={#2+#1}
1689 Then the cursor jumps first to the right and then to the left where the
1691 This can be confusing.
1692 One could think about a visual movement mode by taking the position of
1693 the macro argument insets into account to find the next inset for the cursor
1695 This should be doable.