/// packages that are automatically skipped if loaded by LyX
const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb",
"amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color",
-"float", "fontspec", "graphicx", "hhline", "ifthen", "longtable", "makeidx",
-"multirow", "nomencl", "pdfpages", "prettyref", "refstyle", "rotating",
+"float", "fontspec", "framed", "graphicx", "hhline", "ifthen", "longtable",
+"makeidx", "multirow", "nomencl", "pdfpages", "prettyref", "refstyle", "rotating",
"rotfloat", "splitidx", "setspace", "subscript", "textcomp", "tipa", "tipx",
"tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xunicode", 0};
-// used for the handling of \newindex
-int index_number = 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';
Preamble::Preamble() : one_language(true), explicit_babel(false),
- title_layout_found(false), h_font_cjk_set(false)
+ title_layout_found(false), index_number(0), h_font_cjk_set(false)
{
//h_backgroundcolor;
//h_boxbgcolor;
//h_float_placement;
//h_fontcolor;
h_fontencoding = "default";
- h_font_roman = "default";
- h_font_sans = "default";
- h_font_typewriter = "default";
- h_font_math = "auto";
+ h_font_roman[0] = "default";
+ h_font_roman[1] = "default";
+ h_font_sans[0] = "default";
+ h_font_sans[1] = "default";
+ h_font_typewriter[0] = "default";
+ h_font_typewriter[1] = "default";
+ h_font_math[0] = "auto";
+ h_font_math[1] = "auto";
h_font_default_family = "default";
h_use_non_tex_fonts = false;
h_font_sc = "false";
h_font_osf = "false";
- h_font_sf_scale = "100";
- h_font_tt_scale = "100";
+ h_font_sf_scale[0] = "100";
+ h_font_sf_scale[1] = "100";
+ h_font_tt_scale[0] = "100";
+ h_font_tt_scale[1] = "100";
//h_font_cjk
h_graphics = "default";
h_default_output_format = "default";
h_secnumdepth = "3";
h_shortcut[0] = "idx";
h_spacing = "single";
+ h_save_transient_properties = "true";
h_suppress_date = "false";
h_textclass = "article";
h_tocdepth = "3";
void Preamble::handle_package(Parser &p, string const & name,
- string const & opts, bool in_lyx_preamble)
+ string const & opts, bool in_lyx_preamble,
+ bool detectEncoding)
{
vector<string> options = split_options(opts);
add_package(name, options);
// roman fonts
if (is_known(name, known_roman_fonts))
- h_font_roman = name;
+ h_font_roman[0] = name;
if (name == "fourier") {
- h_font_roman = "utopia";
+ h_font_roman[0] = "utopia";
// when font uses real small capitals
if (opts == "expert")
h_font_sc = "true";
}
if (name == "garamondx") {
- h_font_roman = "garamondx";
+ h_font_roman[0] = "garamondx";
if (opts == "osfI")
h_font_osf = "true";
}
if (name == "libertine") {
- h_font_roman = "libertine";
+ h_font_roman[0] = "libertine";
// this automatically invokes biolinum
- h_font_sans = "biolinum";
+ h_font_sans[0] = "biolinum";
if (opts == "osf")
h_font_osf = "true";
else if (opts == "lining")
}
if (name == "libertine-type1") {
- h_font_roman = "libertine";
+ h_font_roman[0] = "libertine";
// NOTE: contrary to libertine.sty, libertine-type1
// does not automatically invoke biolinum
if (opts == "lining")
if (name == "mathdesign") {
if (opts.find("charter") != string::npos)
- h_font_roman = "md-charter";
+ h_font_roman[0] = "md-charter";
if (opts.find("garamond") != string::npos)
- h_font_roman = "md-garamond";
+ h_font_roman[0] = "md-garamond";
if (opts.find("utopia") != string::npos)
- h_font_roman = "md-utopia";
+ h_font_roman[0] = "md-utopia";
if (opts.find("expert") != string::npos) {
h_font_sc = "true";
h_font_osf = "true";
}
else if (name == "mathpazo")
- h_font_roman = "palatino";
+ h_font_roman[0] = "palatino";
else if (name == "mathptmx")
- h_font_roman = "times";
+ h_font_roman[0] = "times";
// sansserif fonts
if (is_known(name, known_sans_fonts)) {
- h_font_sans = name;
+ h_font_sans[0] = name;
if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_sf_scale))
+ if (scale_as_percentage(opts, h_font_sf_scale[0]))
options.clear();
}
}
if (name == "biolinum-type1") {
- h_font_sans = "biolinum";
+ h_font_sans[0] = "biolinum";
// biolinum can have several options, e.g. [osf,scaled=0.97]
string::size_type pos = opts.find("osf");
if (pos != string::npos)
// fourier can be set as roman font _only_
// fourier as typewriter is handled in handling of \ttdefault
if (name != "fourier") {
- h_font_typewriter = name;
+ h_font_typewriter[0] = name;
if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_tt_scale))
+ if (scale_as_percentage(opts, h_font_tt_scale[0]))
options.clear();
}
}
}
if (name == "libertineMono-type1") {
- h_font_typewriter = "libertine-mono";
+ h_font_typewriter[0] = "libertine-mono";
}
// font uses old-style figure
// math fonts
if (is_known(name, known_math_fonts))
- h_font_math = name;
+ h_font_math[0] = name;
if (name == "newtxmath") {
if (opts.empty())
- h_font_math = "newtxmath";
+ h_font_math[0] = "newtxmath";
else if (opts == "garamondx")
- h_font_math = "garamondx-ntxm";
+ h_font_math[0] = "garamondx-ntxm";
else if (opts == "libertine")
- h_font_math = "libertine-ntxm";
+ h_font_math[0] = "libertine-ntxm";
else if (opts == "minion")
- h_font_math = "minion-ntxm";
+ h_font_math[0] = "minion-ntxm";
}
if (name == "iwona")
if (opts == "math")
- h_font_math = "iwona-math";
+ h_font_math[0] = "iwona-math";
if (name == "kurier")
if (opts == "math")
- h_font_math = "kurier-math";
+ h_font_math[0] = "kurier-math";
// after the detection and handling of special cases, we can remove the
// fonts, otherwise they would appear in the preamble, see bug #7856
string const encoding = options.back();
Encoding const * const enc = encodings.fromLaTeXName(
encoding, Encoding::inputenc, true);
- if (!enc)
- cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl;
- else {
+ if (!enc) {
+ if (!detectEncoding)
+ cerr << "Unknown encoding " << encoding
+ << ". Ignoring." << std::endl;
+ } else {
if (!enc->unsafe() && options.size() == 1 && one_language == true)
h_inputencoding = enc->name();
p.setEncoding(enc->iconvName());
}
// We need to do something with the options...
- if (!options.empty())
+ if (!options.empty() && !detectEncoding)
cerr << "Ignoring options '" << join(options, ",")
<< "' of package " << name << '.' << endl;
<< "\\lyxformat " << LYX_FORMAT << '\n'
<< "\\begin_document\n"
<< "\\begin_header\n"
+ << "\\save_transient_properties " << h_save_transient_properties << "\n"
<< "\\origin " << origin << "\n"
<< "\\textclass " << h_textclass << "\n";
string const raw = subdoc ? empty_string() : h_preamble.str();
<< "\\language_package " << h_language_package << "\n"
<< "\\inputencoding " << h_inputencoding << "\n"
<< "\\fontencoding " << h_fontencoding << "\n"
- << "\\font_roman " << h_font_roman << "\n"
- << "\\font_sans " << h_font_sans << "\n"
- << "\\font_typewriter " << h_font_typewriter << "\n"
- << "\\font_math " << h_font_math << "\n"
+ << "\\font_roman \"" << h_font_roman[0]
+ << "\" \"" << h_font_roman[1] << "\"\n"
+ << "\\font_sans \"" << h_font_sans[0] << "\" \"" << h_font_sans[1] << "\"\n"
+ << "\\font_typewriter \"" << h_font_typewriter[0]
+ << "\" \"" << h_font_typewriter[1] << "\"\n"
+ << "\\font_math \"" << h_font_math[0] << "\" \"" << h_font_math[1] << "\"\n"
<< "\\font_default_family " << h_font_default_family << "\n"
<< "\\use_non_tex_fonts " << (h_use_non_tex_fonts ? "true" : "false") << '\n'
<< "\\font_sc " << h_font_sc << "\n"
<< "\\font_osf " << h_font_osf << "\n"
- << "\\font_sf_scale " << h_font_sf_scale << "\n"
- << "\\font_tt_scale " << h_font_tt_scale << '\n';
+ << "\\font_sf_scale " << h_font_sf_scale[0]
+ << ' ' << h_font_sf_scale[1] << '\n'
+ << "\\font_tt_scale " << h_font_tt_scale[0]
+ << ' ' << h_font_tt_scale[1] << '\n';
if (!h_font_cjk.empty())
os << "\\font_cjk " << h_font_cjk << '\n';
os << "\\graphics " << h_graphics << '\n'
<< "\\use_hyperref " << h_use_hyperref << '\n';
if (h_use_hyperref == "true") {
if (!h_pdf_title.empty())
- os << "\\pdf_title \"" << h_pdf_title << "\"\n";
+ os << "\\pdf_title " << Lexer::quoteString(h_pdf_title) << '\n';
if (!h_pdf_author.empty())
- os << "\\pdf_author \"" << h_pdf_author << "\"\n";
+ os << "\\pdf_author " << Lexer::quoteString(h_pdf_author) << '\n';
if (!h_pdf_subject.empty())
- os << "\\pdf_subject \"" << h_pdf_subject << "\"\n";
+ os << "\\pdf_subject " << Lexer::quoteString(h_pdf_subject) << '\n';
if (!h_pdf_keywords.empty())
- os << "\\pdf_keywords \"" << h_pdf_keywords << "\"\n";
+ os << "\\pdf_keywords " << Lexer::quoteString(h_pdf_keywords) << '\n';
os << "\\pdf_bookmarks " << h_pdf_bookmarks << "\n"
"\\pdf_bookmarksnumbered " << h_pdf_bookmarksnumbered << "\n"
"\\pdf_bookmarksopen " << h_pdf_bookmarksopen << "\n"
if (!h_pdf_pagemode.empty())
os << "\\pdf_pagemode " << h_pdf_pagemode << '\n';
if (!h_pdf_quoted_options.empty())
- os << "\\pdf_quoted_options \"" << h_pdf_quoted_options << "\"\n";
+ os << "\\pdf_quoted_options " << Lexer::quoteString(h_pdf_quoted_options) << '\n';
}
os << "\\papersize " << h_papersize << "\n"
<< "\\use_geometry " << h_use_geometry << '\n';
{
// initialize fixed types
special_columns_['D'] = 3;
+ parse(p, forceclass, false, tc);
+}
+
+
+void Preamble::parse(Parser & p, string const & forceclass,
+ bool detectEncoding, TeX2LyXDocClass & tc)
+{
bool is_full_document = false;
bool is_lyx_file = false;
bool in_lyx_preamble = false;
}
p.reset();
+ if (detectEncoding && !is_full_document)
+ return;
+
while (is_full_document && p.good()) {
+ if (detectEncoding && h_inputencoding != "auto" &&
+ h_inputencoding != "default")
+ return;
+
Token const & t = p.get_token();
#ifdef FILEDEBUG
- cerr << "t: " << t << "\n";
+ if (!detectEncoding)
+ cerr << "t: " << t << '\n';
#endif
//
if (comment.size() > magicXeLaTeX.size()
&& comment.substr(0, magicXeLaTeX.size()) == magicXeLaTeX
&& h_inputencoding == "auto") {
- cerr << "XeLaTeX comment found, switching to UTF8\n";
+ if (!detectEncoding)
+ cerr << "XeLaTeX comment found, switching to UTF8\n";
h_inputencoding = "utf8";
}
smatch sub;
else if (t.cs() == "setmainfont") {
// we don't care about the option
p.hasOpt() ? p.getOpt() : string();
- h_font_roman = p.getArg('{', '}');
+ h_font_roman[1] = p.getArg('{', '}');
}
else if (t.cs() == "setsansfont" || t.cs() == "setmonofont") {
}
if (t.cs() == "setsansfont") {
if (!scale.empty())
- h_font_sf_scale = scale;
- h_font_sans = p.getArg('{', '}');
+ h_font_sf_scale[1] = scale;
+ h_font_sans[1] = p.getArg('{', '}');
} else {
if (!scale.empty())
- h_font_tt_scale = scale;
- h_font_typewriter = p.getArg('{', '}');
+ h_font_tt_scale[1] = scale;
+ h_font_typewriter[1] = p.getArg('{', '}');
}
}
// check the case that a standard color is used
if (space.empty() && is_known(argument, known_basic_colors)) {
h_fontcolor = rgbcolor2code(argument);
- preamble.registerAutomaticallyLoadedPackage("color");
+ registerAutomaticallyLoadedPackage("color");
} else if (space.empty() && argument == "document_fontcolor")
- preamble.registerAutomaticallyLoadedPackage("color");
+ registerAutomaticallyLoadedPackage("color");
// check the case that LyX's document_fontcolor is defined
// but not used for \color
else {
if (is_known(argument, known_basic_colors)) {
h_backgroundcolor = rgbcolor2code(argument);
} else if (argument == "page_backgroundcolor")
- preamble.registerAutomaticallyLoadedPackage("color");
+ registerAutomaticallyLoadedPackage("color");
// check the case that LyX's page_backgroundcolor is defined
// but not used for \pagecolor
else {
string const body2 = p.verbatim_item();
// only non-lyxspecific stuff
if (in_lyx_preamble &&
- (name == "subref" || name == "thmref" || name == "lemref"))
+ (name == "subsecref" || name == "thmref" || name == "lemref"))
p.skip_spaces();
else {
ostringstream ss;
(name == "\\providecommand\\partref[1]{\\ref{part:#1}}"
|| name == "\\providecommand\\chapref[1]{\\ref{chap:#1}}"
|| name == "\\providecommand\\secref[1]{\\ref{sec:#1}}"
- || name == "\\providecommand\\subref[1]{\\ref{sub:#1}}"
+ || name == "\\providecommand\\subsecref[1]{\\ref{subsec:#1}}"
|| name == "\\providecommand\\parref[1]{\\ref{par:#1}}"
|| name == "\\providecommand\\figref[1]{\\ref{fig:#1}}"
|| name == "\\providecommand\\tabref[1]{\\ref{tab:#1}}"
// font settings
if (name == "\\rmdefault")
if (is_known(body, known_roman_fonts)) {
- h_font_roman = body;
+ h_font_roman[0] = body;
p.skip_spaces();
in_lyx_preamble = true;
}
if (name == "\\sfdefault")
if (is_known(body, known_sans_fonts)) {
- h_font_sans = body;
+ h_font_sans[0] = body;
p.skip_spaces();
in_lyx_preamble = true;
}
if (name == "\\ttdefault")
if (is_known(body, known_typewriter_fonts)) {
- h_font_typewriter = body;
+ h_font_typewriter[0] = body;
p.skip_spaces();
in_lyx_preamble = true;
}
in_lyx_preamble = true;
}
- // remove the lyxdot definition that is re-added by LyX
+ // remove LyX-specific definitions that are re-added by LyX
// if necessary
- if (name == "\\lyxdot") {
+ // \lyxline is an ancient command that is converted by tex2lyx into
+ // a \rule therefore remove its preamble code
+ if (name == "\\lyxdot" || name == "\\lyxarrow"
+ || name == "\\lyxline" || name == "\\LyX") {
p.skip_spaces();
in_lyx_preamble = true;
}
vector<string>::const_iterator end = vecnames.end();
for (; it != end; ++it)
handle_package(p, trimSpaceAndEol(*it), options,
- in_lyx_preamble);
+ in_lyx_preamble, detectEncoding);
}
else if (t.cs() == "inputencoding") {
string const encoding = p.getArg('{','}');
Encoding const * const enc = encodings.fromLaTeXName(
encoding, Encoding::inputenc, true);
- if (!enc)
- cerr << "Unknown encoding " << encoding << ". Ignoring." << std::endl;
- else {
+ if (!enc) {
+ if (!detectEncoding)
+ cerr << "Unknown encoding " << encoding
+ << ". Ignoring." << std::endl;
+ } else {
if (!enc->unsafe())
h_inputencoding = enc->name();
p.setEncoding(enc->iconvName());
}
else if (t.cs() == "newtheorem") {
+ bool star = false;
+ if (p.next_token().character() == '*') {
+ p.get_token();
+ star = true;
+ }
string const name = p.getArg('{', '}');
string const opt1 = p.getFullOpt();
string const opt2 = p.getFullOpt();
string const body = p.verbatim_item();
string const opt3 = p.getFullOpt();
+ string const cmd = star ? "\\newtheorem*" : "\\newtheorem";
- add_known_theorem(name, opt1, !opt2.empty(),
- from_utf8("\\newtheorem{" + name + '}' +
- opt1 + opt2 + '{' + body + '}' + opt3));
+ string const complete = cmd + "{" + name + '}' +
+ opt1 + opt2 + '{' + body + '}' + opt3;
+
+ add_known_theorem(name, opt1, !opt2.empty(), from_utf8(complete));
if (!in_lyx_preamble)
- h_preamble << "\\newtheorem{" << name << '}'
- << opt1 << opt2 << '{' << '}' << opt3;
+ h_preamble << complete;
}
else if (t.cs() == "def") {
}
+string Preamble::parseEncoding(Parser & p, string const & forceclass)
+{
+ TeX2LyXDocClass dummy;
+ parse(p, forceclass, true, dummy);
+ if (h_inputencoding != "auto" && h_inputencoding != "default")
+ return h_inputencoding;
+ return "";
+}
+
+
string babel2lyx(string const & language)
{
char const * const * where = is_known(language, known_languages);