]> git.lyx.org Git - features.git/commitdiff
do not hardcode packages loaded by external insets
authorGeorg Baum <georg.baum@post.rwth-aachen.de>
Tue, 13 Dec 2011 19:40:05 +0000 (19:40 +0000)
committerGeorg Baum <georg.baum@post.rwth-aachen.de>
Tue, 13 Dec 2011 19:40:05 +0000 (19:40 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40491 a592a061-630c-0410-9148-cb99ea01b6c8

src/VSpace.cpp
src/lengthcommon.cpp
src/tex2lyx/CMakeLists.txt
src/tex2lyx/Makefile.am
src/tex2lyx/Preamble.cpp
src/tex2lyx/text.cpp

index da9133a4c090727525e11a413a82550439bd9c92..72315072d61c8b646e47655f54fb0f57931ff8d1 100644 (file)
 
 #include "support/lassert.h"
 
-#include <cstring>
-
 using namespace std;
 using namespace lyx::support;
 
 
 namespace lyx {
 
-namespace {
-
-/// used to return numeric values in parsing vspace
-double number[4] = { 0, 0, 0, 0 };
-
-/// used to return unit types in parsing vspace
-Length::UNIT unit[4] = {
-       Length::UNIT_NONE,
-       Length::UNIT_NONE,
-       Length::UNIT_NONE,
-       Length::UNIT_NONE
-};
-
-/// the current position in the number array
-int number_index;
-/// the current position in the unit array
-int unit_index;
-
-/// skip n characters of input
-inline void lyx_advance(string & data, size_t n)
-{
-       data.erase(0, n);
-}
-
-
-/// return true when the input is at the end
-inline bool isEndOfData(string const & data)
-{
-       return ltrim(data).empty();
-}
-
-
-/**
- * nextToken -  return the next token in the input
- * @param data input string
- * @return a char representing the type of token returned
- *
- * The possible return values are :
- *     +       stretch indicator for glue length
- *     -       shrink indicator for glue length
- *     n       a numeric value (stored in number array)
- *     u       a unit type (stored in unit array)
- *     E       parse error
- */
-char nextToken(string & data)
-{
-       data = ltrim(data);
-
-       if (data.empty())
-               return '\0';
-
-       if (data[0] == '+') {
-               lyx_advance(data, 1);
-               return '+';
-       }
-
-       if (prefixIs(data, "plus")) {
-               lyx_advance(data, 4);
-               return '+';
-       }
-
-       if (data[0] == '-') {
-               lyx_advance(data, 1);
-               return '-';
-       }
-
-       if (prefixIs(data, "minus")) {
-               lyx_advance(data, 5);
-               return '-';
-       }
-
-       size_t i = data.find_first_not_of("0123456789.");
-
-       if (i != 0) {
-               if (number_index > 3)
-                       return 'E';
-
-               string buffer;
-
-               // we have found some number
-               if (i == string::npos) {
-                       buffer = data;
-                       i = data.size() + 1;
-               } else {
-                       buffer = data.substr(0, i);
-               }
-
-               lyx_advance(data, i);
-
-               if (isStrDbl(buffer)) {
-                       number[number_index] = convert<double>(buffer);
-                       ++number_index;
-                       return 'n';
-               }
-               return 'E';
-       }
-
-       i = data.find_first_not_of("abcdefghijklmnopqrstuvwxyz%");
-       if (i != 0) {
-               if (unit_index > 3)
-                       return 'E';
-
-               string buffer;
-
-               // we have found some alphabetical string
-               if (i == string::npos) {
-                       buffer = data;
-                       i = data.size() + 1;
-               } else {
-                       buffer = data.substr(0, i);
-               }
-
-               // possibly we have "mmplus" string or similar
-               if (buffer.size() > 5 &&
-                               (buffer.substr(2, 4) == string("plus") ||
-                                buffer.substr(2, 5) == string("minus")))
-               {
-                       lyx_advance(data, 2);
-                       unit[unit_index] = unitFromString(buffer.substr(0, 2));
-               } else {
-                       lyx_advance(data, i);
-                       unit[unit_index] = unitFromString(buffer);
-               }
-
-               if (unit[unit_index] != Length::UNIT_NONE) {
-                       ++unit_index;
-                       return 'u';
-               }
-               return 'E';  // Error
-       }
-       return 'E';  // Error
-}
-
-
-/// latex representation of a vspace
-struct LaTeXLength {
-       char const * pattern;
-       int  plus_val_index;
-       int  minus_val_index;
-       int  plus_uni_index;
-       int  minus_uni_index;
-};
-
-
-/// the possible formats for a vspace string
-LaTeXLength table[] = {
-       { "nu",       0, 0, 0, 0 },
-       { "nu+nu",    2, 0, 2, 0 },
-       { "nu+nu-nu", 2, 3, 2, 3 },
-       { "nu+-nu",   2, 2, 2, 2 },
-       { "nu-nu",    0, 2, 0, 2 },
-       { "nu-nu+nu", 3, 2, 3, 2 },
-       { "nu-+nu",   2, 2, 2, 2 },
-       { "n+nu",     2, 0, 1, 0 },
-       { "n+n-nu",   2, 3, 1, 1 },
-       { "n+-nu",    2, 2, 1, 1 },
-       { "n-nu",     0, 2, 0, 1 },
-       { "n-n+nu",   3, 2, 1, 1 },
-       { "n-+nu",    2, 2, 1, 1 },
-       { "",         0, 0, 0, 0 }   // sentinel, must be empty
-};
-
-
-} // namespace anon
-
-const char * stringFromUnit(int unit)
-{
-       if (unit < 0 || unit > num_units)
-               return 0;
-       return unit_name[unit];
-}
-
-
-bool isValidGlueLength(string const & data, GlueLength * result)
-{
-       // This parser is table-driven.  First, it constructs a "pattern"
-       // that describes the sequence of tokens in "data".  For example,
-       // "n-nu" means: number, minus sign, number, unit.  As we go along,
-       // numbers and units are stored into static arrays.  Then, "pattern"
-       // is searched in the "table".  If it is found, the associated
-       // table entries tell us which number and unit should go where
-       // in the Length structure.  Example: if "data" has the "pattern"
-       // "nu+nu-nu", the associated table entries are "2, 3, 2, 3".
-       // That means, "plus_val" is the second number that was seen
-       // in the input, "minus_val" is the third number, and "plus_uni"
-       // and "minus_uni" are the second and third units, respectively.
-       // ("val" and "uni" are always the first items seen in "data".)
-       // This is the most elegant solution I could find -- a straight-
-       // forward approach leads to very long, tedious code that would be
-       // much harder to understand and maintain. (AS)
-
-       if (data.empty())
-               return true;
-       string buffer = ltrim(data);
-
-       // To make isValidGlueLength recognize negative values as
-       // the first number this little hack is needed:
-       int val_sign = 1; // positive as default
-       switch (buffer[0]) {
-       case '-':
-               lyx_advance(buffer, 1);
-               val_sign = -1;
-               break;
-       case '+':
-               lyx_advance(buffer, 1);
-               break;
-       default:
-               break;
-       }
-       // end of hack
-
-       number_index = unit_index = 1;  // entries at index 0 are sentinels
-
-       // construct "pattern" from "data"
-       size_t const pattern_max_size = 20;
-       string pattern;
-       while (!isEndOfData(buffer)) {
-               if (pattern.size() > pattern_max_size)
-                       return false;
-               char const c = nextToken(buffer);
-               if (c == 'E')
-                       return false;
-               pattern.push_back(c);
-       }
-
-       // search "pattern" in "table"
-       size_t table_index = 0;
-       while (pattern != table[table_index].pattern) {
-               ++table_index;
-               if (!*table[table_index].pattern)
-                       return false;
-       }
-
-       // Get the values from the appropriate places.  If an index
-       // is zero, the corresponding array value is zero or UNIT_NONE,
-       // so we needn't check this.
-       if (result) {
-               result->len_.value  (number[1] * val_sign);
-               result->len_.unit   (unit[1]);
-               result->plus_.value (number[table[table_index].plus_val_index]);
-               result->plus_.unit  (unit  [table[table_index].plus_uni_index]);
-               result->minus_.value(number[table[table_index].minus_val_index]);
-               result->minus_.unit (unit  [table[table_index].minus_uni_index]);
-       }
-       return true;
-}
-
-
-bool isValidLength(string const & data, Length * result)
-{
-       // This is a trimmed down version of isValidGlueLength.
-       // The parser may seem overkill for lengths without
-       // glue, but since we already have it, using it is
-       // easier than writing something from scratch.
-       if (data.empty())
-               return true;
-
-       string   buffer = data;
-       int      pattern_index = 0;
-       char     pattern[3];
-
-       // To make isValidLength recognize negative values
-       // this little hack is needed:
-       int val_sign = 1; // positive as default
-       switch (buffer[0]) {
-       case '-':
-               lyx_advance(buffer, 1);
-               val_sign = -1;
-               break;
-       case '+':
-               lyx_advance(buffer, 1);
-               // fall through
-       default:
-               // no action
-               break;
-       }
-       // end of hack
-
-       number_index = unit_index = 1;  // entries at index 0 are sentinels
-
-       // construct "pattern" from "data"
-       while (!isEndOfData(buffer)) {
-               if (pattern_index > 2)
-                       return false;
-               pattern[pattern_index] = nextToken(buffer);
-               if (pattern[pattern_index] == 'E')
-                       return false;
-               ++pattern_index;
-       }
-       pattern[pattern_index] = '\0';
-
-       // only the most basic pattern is accepted here
-       if (strcmp(pattern, "nu") != 0)
-               return false;
-
-       // It _was_ a correct length string.
-       // Store away the values we found.
-       if (result) {
-               result->val_  = number[1] * val_sign;
-               result->unit_ = unit[1];
-       }
-       return true;
-}
-
-
 //
 //  VSpace class
 //
index 0fa43359d66766e7078e2818cc78e085498af7a3..59ba5070020e90d469de872377fa77cd1e69ad9d 100644 (file)
 
 #include <config.h>
 
-#include "support/gettext.h"
 #include "Length.h"
 
+#include "support/convert.h"
+#include "support/gettext.h"
+#include "support/lassert.h"
+#include "support/lstrings.h"
+
+#include <cstring>
 #include <string>
 
 using namespace std;
+using namespace lyx::support;
+
 
 namespace lyx {
 
@@ -49,4 +56,308 @@ Length::UNIT unitFromString(string const & data)
 }
 
 
+namespace {
+
+/// used to return numeric values in parsing vspace
+double number[4] = { 0, 0, 0, 0 };
+
+/// used to return unit types in parsing vspace
+Length::UNIT unit[4] = {
+       Length::UNIT_NONE,
+       Length::UNIT_NONE,
+       Length::UNIT_NONE,
+       Length::UNIT_NONE
+};
+
+/// the current position in the number array
+int number_index;
+/// the current position in the unit array
+int unit_index;
+
+/// skip n characters of input
+inline void lyx_advance(string & data, size_t n)
+{
+       data.erase(0, n);
+}
+
+
+/// return true when the input is at the end
+inline bool isEndOfData(string const & data)
+{
+       return ltrim(data).empty();
+}
+
+
+/**
+ * nextToken -  return the next token in the input
+ * @param data input string
+ * @return a char representing the type of token returned
+ *
+ * The possible return values are :
+ *     +       stretch indicator for glue length
+ *     -       shrink indicator for glue length
+ *     n       a numeric value (stored in number array)
+ *     u       a unit type (stored in unit array)
+ *     E       parse error
+ */
+char nextToken(string & data)
+{
+       data = ltrim(data);
+
+       if (data.empty())
+               return '\0';
+
+       if (data[0] == '+') {
+               lyx_advance(data, 1);
+               return '+';
+       }
+
+       if (prefixIs(data, "plus")) {
+               lyx_advance(data, 4);
+               return '+';
+       }
+
+       if (data[0] == '-') {
+               lyx_advance(data, 1);
+               return '-';
+       }
+
+       if (prefixIs(data, "minus")) {
+               lyx_advance(data, 5);
+               return '-';
+       }
+
+       size_t i = data.find_first_not_of("0123456789.");
+
+       if (i != 0) {
+               if (number_index > 3)
+                       return 'E';
+
+               string buffer;
+
+               // we have found some number
+               if (i == string::npos) {
+                       buffer = data;
+                       i = data.size() + 1;
+               } else {
+                       buffer = data.substr(0, i);
+               }
+
+               lyx_advance(data, i);
+
+               if (isStrDbl(buffer)) {
+                       number[number_index] = convert<double>(buffer);
+                       ++number_index;
+                       return 'n';
+               }
+               return 'E';
+       }
+
+       i = data.find_first_not_of("abcdefghijklmnopqrstuvwxyz%");
+       if (i != 0) {
+               if (unit_index > 3)
+                       return 'E';
+
+               string buffer;
+
+               // we have found some alphabetical string
+               if (i == string::npos) {
+                       buffer = data;
+                       i = data.size() + 1;
+               } else {
+                       buffer = data.substr(0, i);
+               }
+
+               // possibly we have "mmplus" string or similar
+               if (buffer.size() > 5 &&
+                               (buffer.substr(2, 4) == string("plus") ||
+                                buffer.substr(2, 5) == string("minus")))
+               {
+                       lyx_advance(data, 2);
+                       unit[unit_index] = unitFromString(buffer.substr(0, 2));
+               } else {
+                       lyx_advance(data, i);
+                       unit[unit_index] = unitFromString(buffer);
+               }
+
+               if (unit[unit_index] != Length::UNIT_NONE) {
+                       ++unit_index;
+                       return 'u';
+               }
+               return 'E';  // Error
+       }
+       return 'E';  // Error
+}
+
+
+/// latex representation of a vspace
+struct LaTeXLength {
+       char const * pattern;
+       int  plus_val_index;
+       int  minus_val_index;
+       int  plus_uni_index;
+       int  minus_uni_index;
+};
+
+
+/// the possible formats for a vspace string
+LaTeXLength table[] = {
+       { "nu",       0, 0, 0, 0 },
+       { "nu+nu",    2, 0, 2, 0 },
+       { "nu+nu-nu", 2, 3, 2, 3 },
+       { "nu+-nu",   2, 2, 2, 2 },
+       { "nu-nu",    0, 2, 0, 2 },
+       { "nu-nu+nu", 3, 2, 3, 2 },
+       { "nu-+nu",   2, 2, 2, 2 },
+       { "n+nu",     2, 0, 1, 0 },
+       { "n+n-nu",   2, 3, 1, 1 },
+       { "n+-nu",    2, 2, 1, 1 },
+       { "n-nu",     0, 2, 0, 1 },
+       { "n-n+nu",   3, 2, 1, 1 },
+       { "n-+nu",    2, 2, 1, 1 },
+       { "",         0, 0, 0, 0 }   // sentinel, must be empty
+};
+
+
+} // namespace anon
+
+const char * stringFromUnit(int unit)
+{
+       if (unit < 0 || unit > num_units)
+               return 0;
+       return unit_name[unit];
+}
+
+
+bool isValidGlueLength(string const & data, GlueLength * result)
+{
+       // This parser is table-driven.  First, it constructs a "pattern"
+       // that describes the sequence of tokens in "data".  For example,
+       // "n-nu" means: number, minus sign, number, unit.  As we go along,
+       // numbers and units are stored into static arrays.  Then, "pattern"
+       // is searched in the "table".  If it is found, the associated
+       // table entries tell us which number and unit should go where
+       // in the Length structure.  Example: if "data" has the "pattern"
+       // "nu+nu-nu", the associated table entries are "2, 3, 2, 3".
+       // That means, "plus_val" is the second number that was seen
+       // in the input, "minus_val" is the third number, and "plus_uni"
+       // and "minus_uni" are the second and third units, respectively.
+       // ("val" and "uni" are always the first items seen in "data".)
+       // This is the most elegant solution I could find -- a straight-
+       // forward approach leads to very long, tedious code that would be
+       // much harder to understand and maintain. (AS)
+
+       if (data.empty())
+               return true;
+       string buffer = ltrim(data);
+
+       // To make isValidGlueLength recognize negative values as
+       // the first number this little hack is needed:
+       int val_sign = 1; // positive as default
+       switch (buffer[0]) {
+       case '-':
+               lyx_advance(buffer, 1);
+               val_sign = -1;
+               break;
+       case '+':
+               lyx_advance(buffer, 1);
+               break;
+       default:
+               break;
+       }
+       // end of hack
+
+       number_index = unit_index = 1;  // entries at index 0 are sentinels
+
+       // construct "pattern" from "data"
+       size_t const pattern_max_size = 20;
+       string pattern;
+       while (!isEndOfData(buffer)) {
+               if (pattern.size() > pattern_max_size)
+                       return false;
+               char const c = nextToken(buffer);
+               if (c == 'E')
+                       return false;
+               pattern.push_back(c);
+       }
+
+       // search "pattern" in "table"
+       size_t table_index = 0;
+       while (pattern != table[table_index].pattern) {
+               ++table_index;
+               if (!*table[table_index].pattern)
+                       return false;
+       }
+
+       // Get the values from the appropriate places.  If an index
+       // is zero, the corresponding array value is zero or UNIT_NONE,
+       // so we needn't check this.
+       if (result) {
+               result->len_.value  (number[1] * val_sign);
+               result->len_.unit   (unit[1]);
+               result->plus_.value (number[table[table_index].plus_val_index]);
+               result->plus_.unit  (unit  [table[table_index].plus_uni_index]);
+               result->minus_.value(number[table[table_index].minus_val_index]);
+               result->minus_.unit (unit  [table[table_index].minus_uni_index]);
+       }
+       return true;
+}
+
+
+bool isValidLength(string const & data, Length * result)
+{
+       // This is a trimmed down version of isValidGlueLength.
+       // The parser may seem overkill for lengths without
+       // glue, but since we already have it, using it is
+       // easier than writing something from scratch.
+       if (data.empty())
+               return true;
+
+       string   buffer = data;
+       int      pattern_index = 0;
+       char     pattern[3];
+
+       // To make isValidLength recognize negative values
+       // this little hack is needed:
+       int val_sign = 1; // positive as default
+       switch (buffer[0]) {
+       case '-':
+               lyx_advance(buffer, 1);
+               val_sign = -1;
+               break;
+       case '+':
+               lyx_advance(buffer, 1);
+               // fall through
+       default:
+               // no action
+               break;
+       }
+       // end of hack
+
+       number_index = unit_index = 1;  // entries at index 0 are sentinels
+
+       // construct "pattern" from "data"
+       while (!isEndOfData(buffer)) {
+               if (pattern_index > 2)
+                       return false;
+               pattern[pattern_index] = nextToken(buffer);
+               if (pattern[pattern_index] == 'E')
+                       return false;
+               ++pattern_index;
+       }
+       pattern[pattern_index] = '\0';
+
+       // only the most basic pattern is accepted here
+       if (strcmp(pattern, "nu") != 0)
+               return false;
+
+       // It _was_ a correct length string.
+       // Store away the values we found.
+       if (result) {
+               result->val_  = number[1] * val_sign;
+               result->unit_ = unit[1];
+       }
+       return true;
+}
+
 } // namespace lyx
index 08ce121c0004fb8966c623714156093a98104972..00a577f323af8759124cf86076343a64bd8df662 100644 (file)
@@ -12,9 +12,10 @@ project(${_tex2lyx})
 set(LINKED_sources ${TOP_SRC_DIR}/src/lengthcommon.cpp)
 set(LINKED_headers)
 
-foreach(_src insets/InsetLayout Author Color Counters
-       Encoding FloatList Floating FontInfo LaTeXPackages
-       Layout LayoutFile LayoutModuleList Lexer ModuleList TextClass
+foreach(_src graphics/GraphicsParams insets/ExternalTemplate
+       insets/ExternalTransforms insets/InsetLayout Author Color Counters
+       Encoding FloatList Floating FontInfo LaTeXPackages Layout
+       LayoutFile LayoutModuleList Length Lexer ModuleList TextClass
        Spacing version)
        list(APPEND LINKED_sources ${TOP_SRC_DIR}/src/${_src}.cpp)
        list(APPEND LINKED_headers ${TOP_SRC_DIR}/src/${_src}.h)
index 04aa8ec3b6e9d9a6cd1e72cd47c16735e653bf29..7406bb2ffe950e9ef45c274f94f78fd058797dd2 100644 (file)
@@ -36,17 +36,20 @@ LINKED_FILES = \
        ../FloatList.cpp \
        ../Floating.cpp \
        ../FontInfo.cpp \
+       ../graphics/GraphicsParams.cpp \
+       ../insets/ExternalTemplate.cpp \
+       ../insets/ExternalTransforms.cpp \
        ../insets/InsetLayout.cpp \
        ../LaTeXPackages.cpp \
        ../Layout.cpp \
        ../LayoutFile.cpp \
        ../LayoutModuleList.cpp \
+       ../Length.cpp \
        ../lengthcommon.cpp \
        ../Lexer.cpp \
        ../ModuleList.cpp \
        ../Spacing.cpp \
        ../TextClass.cpp \
-       ../TextClass.h \
        ../version.cpp
 
 BUILT_SOURCES = $(PCH_FILE)
index dcda4a0f80ba833d59ca907a172ccf153aefcd7d..6ef3aa886bfaaf7f33975f8ef9124f719422fffd 100644 (file)
@@ -171,6 +171,12 @@ const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
 "fontbook", "fontwrap", "mathspec", "philokalia", "polyglossia", "unisugar",
 "xeCJK", "xecolor", "xecyr", "xeindex", "xepersian", "xunicode", 0};
 
+/// packages that are automatically skipped if loaded by LyX
+const char * const known_lyx_packages[] = {"array", "booktabs", "calc",
+"color", "float", "graphicx", "hhline", "ifthen", "longtable", "makeidx",
+"multirow", "nomencl", "pdfpages", "rotfloat", "splitidx", "setspace",
+"subscript", "textcomp", "ulem", "url", "varioref", "verbatim", "wrapfig", 0};
+
 // codes used to remove packages that are loaded automatically by LyX.
 // Syntax: package_beg_sep<name>package_mid_sep<package loading code>package_end_sep
 const char package_beg_sep = '\001';
@@ -715,31 +721,19 @@ void Preamble::handle_package(Parser &p, string const & name,
        else if (name == "prettyref")
                ; // ignore this FIXME: Use the package separator mechanism instead
 
-       else if (name == "pdfpages")
-               ; // ignore this FIXME: Use the package separator mechanism instead
-
        else if (name == "lyxskak") {
                // ignore this and its options
-               if (!options.empty())
-                       options.clear();
+               const char * const o[] = {"ps", "mover", 0};
+               delete_opt(options, o);
        }
 
-       else if (name == "array" || name == "booktabs" || name == "calc" ||
-                name == "color" || name == "float" || name == "hhline" ||
-                name == "ifthen" || name == "longtable" || name == "makeidx" ||
-                name == "multirow" || name == "nomencl" || name == "rotfloat" ||
-                name == "splitidx" || name == "setspace" || name == "subscript" ||
-                name == "textcomp" || name == "ulem" || name == "url" ||
-                name == "varioref" || name == "verbatim" || name == "wrapfig") {
+       else if (is_known(name, known_lyx_packages) && options.empty()) {
                if (!in_lyx_preamble)
                        h_preamble << package_beg_sep << name
                                   << package_mid_sep << "\\usepackage{"
                                   << name << "}\n" << package_end_sep;
        }
 
-       else if (name == "graphicx")
-               ; // ignore this FIXME: Use the package separator mechanism instead
-
        else if (name == "geometry")
                handle_geometry(options);
 
index 97e4919a8674f6b0ad0ee79cb275264f4963fde9..e8180485e87418f54dcd03385625519b651c6933 100644 (file)
@@ -24,6 +24,8 @@
 #include "Length.h"
 #include "Preamble.h"
 
+#include "insets/ExternalTemplate.h"
+
 #include "support/lassert.h"
 #include "support/convert.h"
 #include "support/FileName.h"
@@ -1899,6 +1901,28 @@ void parse_macro(Parser & p, ostream & os, Context & context)
                handle_ert(os, command + ert, context);
 }
 
+
+void registerExternalTemplatePackages(string const & name)
+{
+       external::TemplateManager const & etm = external::TemplateManager::get();
+       external::Template const * const et = etm.getTemplateByName(name);
+       if (!et)
+               return;
+       external::Template::Formats::const_iterator cit = et->formats.end();
+       if (pdflatex)
+               cit = et->formats.find("PDFLaTeX");
+       if (cit == et->formats.end())
+               // If the template has not specified a PDFLaTeX output,
+               // we try the LaTeX format.
+               cit = et->formats.find("LaTeX");
+       if (cit == et->formats.end())
+               return;
+       vector<string>::const_iterator qit = cit->second.requirements.begin();
+       vector<string>::const_iterator qend = cit->second.requirements.end();
+       for (; qit != qend; ++qit)
+               preamble.registerAutomaticallyLoadedPackage(*qit);
+}
+
 } // anonymous namespace
 
 
@@ -2375,14 +2399,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                                macro = false;
                                                // register the packages that are automatically reloaded
                                                // by the Gnumeric template
-                                               // Fixme: InsetExternal.cpp should give us that list
-                                               preamble.registerAutomaticallyLoadedPackage("array");
-                                               preamble.registerAutomaticallyLoadedPackage("calc");
-                                               preamble.registerAutomaticallyLoadedPackage("color");
-                                               preamble.registerAutomaticallyLoadedPackage("hhline");
-                                               preamble.registerAutomaticallyLoadedPackage("ifthen");
-                                               preamble.registerAutomaticallyLoadedPackage("longtable");
-                                               preamble.registerAutomaticallyLoadedPackage("multirow");
+                                               registerExternalTemplatePackages("GnumericSpreadsheet");
                                        }
                                }
                        }
@@ -2719,6 +2736,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // Warn about invalid options.
                        // Check whether some option was given twice.
                        end_inset(os);
+                       preamble.registerAutomaticallyLoadedPackage("graphicx");
                }
 
                else if (t.cs() == "footnote" ||
@@ -3584,6 +3602,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                begin_inset(os, "External\n");
                                os << "\ttemplate XFig\n"
                                   << "\tfilename " << outname << '\n';
+                               registerExternalTemplatePackages("XFig");
                        } else {
                                begin_command_inset(os, "include", name);
                                os << "preview false\n"
@@ -4006,6 +4025,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                os << "\tkeepAspectRatio\n";
                        end_inset(os);
                        context.check_layout(os);
+                       registerExternalTemplatePackages("PDFPages");
                }
 
                else if (t.cs() == "loadgame") {
@@ -4037,6 +4057,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        // after a \loadgame follows a \showboard
                        if (p.get_token().asInput() == "showboard")
                                p.get_token();
+                       registerExternalTemplatePackages("ChessDiagram");
                }
 
                else {