+void InsetMathHull::usedMacros(MathData const & md, DocIterator const & pos,
+ MacroNameSet & macros, MacroNameSet & defs) const
+{
+ MacroNameSet::iterator const end = macros.end();
+
+ for (size_t i = 0; i < md.size(); ++i) {
+ MathMacro const * mi = md[i].nucleus()->asMacro();
+ MathMacroTemplate const * mt = md[i].nucleus()->asMacroTemplate();
+ InsetMathScript const * si = md[i].nucleus()->asScriptInset();
+ InsetMathFracBase const * fi = md[i].nucleus()->asFracBaseInset();
+ InsetMathGrid const * gi = md[i].nucleus()->asGridInset();
+ InsetMathNest const * ni = md[i].nucleus()->asNestInset();
+ if (mi) {
+ // Look for macros in the arguments of this macro.
+ for (idx_type idx = 0; idx < mi->nargs(); ++idx)
+ usedMacros(mi->cell(idx), pos, macros, defs);
+ // Make sure this is a macro defined in the document
+ // (as we also spot the macros in the symbols file)
+ // or that we have not already accounted for it.
+ docstring const name = mi->name();
+ if (macros.find(name) == end)
+ continue;
+ macros.erase(name);
+ // Look for macros in the definition of this macro.
+ MathData ar(pos.buffer());
+ MacroData const * data =
+ pos.buffer()->getMacro(name, pos, true);
+ if (data) {
+ odocstringstream macro_def;
+ data->write(macro_def, true);
+ macro_def << endl;
+ defs.insert(macro_def.str());
+ asArray(data->definition(), ar);
+ }
+ usedMacros(ar, pos, macros, defs);
+ } else if (mt) {
+ MathData ar(pos.buffer());
+ asArray(mt->definition(), ar);
+ usedMacros(ar, pos, macros, defs);
+ } else if (si) {
+ if (!si->nuc().empty())
+ usedMacros(si->nuc(), pos, macros, defs);
+ if (si->hasDown())
+ usedMacros(si->down(), pos, macros, defs);
+ if (si->hasUp())
+ usedMacros(si->up(), pos, macros, defs);
+ } else if (fi || gi) {
+ idx_type nidx = fi ? fi->nargs() : gi->nargs();
+ for (idx_type idx = 0; idx < nidx; ++idx)
+ usedMacros(fi ? fi->cell(idx) : gi->cell(idx),
+ pos, macros, defs);
+ } else if (ni) {
+ usedMacros(ni->cell(0), pos, macros, defs);
+ }
+ }
+}
+
+