From: Georg Baum Date: Tue, 13 Dec 2011 19:40:05 +0000 (+0000) Subject: do not hardcode packages loaded by external insets X-Git-Tag: 2.1.0beta1~2200 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=9b8773826cb2a59eb563e6f98883912ce591047e;p=features.git do not hardcode packages loaded by external insets git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40491 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/VSpace.cpp b/src/VSpace.cpp index da9133a4c0..72315072d6 100644 --- a/src/VSpace.cpp +++ b/src/VSpace.cpp @@ -25,319 +25,12 @@ #include "support/lassert.h" -#include - 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(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 // diff --git a/src/lengthcommon.cpp b/src/lengthcommon.cpp index 0fa43359d6..59ba507002 100644 --- a/src/lengthcommon.cpp +++ b/src/lengthcommon.cpp @@ -12,12 +12,19 @@ #include -#include "support/gettext.h" #include "Length.h" +#include "support/convert.h" +#include "support/gettext.h" +#include "support/lassert.h" +#include "support/lstrings.h" + +#include #include 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(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 diff --git a/src/tex2lyx/CMakeLists.txt b/src/tex2lyx/CMakeLists.txt index 08ce121c00..00a577f323 100644 --- a/src/tex2lyx/CMakeLists.txt +++ b/src/tex2lyx/CMakeLists.txt @@ -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) diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am index 04aa8ec3b6..7406bb2ffe 100644 --- a/src/tex2lyx/Makefile.am +++ b/src/tex2lyx/Makefile.am @@ -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) diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp index dcda4a0f80..6ef3aa886b 100644 --- a/src/tex2lyx/Preamble.cpp +++ b/src/tex2lyx/Preamble.cpp @@ -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_seppackage_mid_seppackage_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); diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 97e4919a86..e8180485e8 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -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::const_iterator qit = cit->second.requirements.begin(); + vector::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 {