char const * const known_coded_ref_commands[] = { "ref", "pageref", "vref",
"vpageref", "formatted", "eqref", 0 };
-/**
- * known polyglossia language names (including variants)
- */
-const char * const polyglossia_languages[] = {
-"albanian", "croatian", "hebrew", "norsk", "swedish", "amharic", "czech", "hindi",
-"nynorsk", "syriac", "arabic", "danish", "icelandic", "occitan", "tamil",
-"armenian", "divehi", "interlingua", "polish", "telugu", "asturian", "dutch",
-"irish", "portuges", "thai", "bahasai", "english", "italian", "romanian", "turkish",
-"bahasam", "esperanto", "lao", "russian", "turkmen", "basque", "estonian", "latin",
-"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "urdu", "brazil",
-"brazilian", "finnish", "lithuanian", "scottish", "usorbian", "breton", "french",
-"lsorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", "slovak",
-"welsh", "catalan", "german", "malayalam", "slovenian", "coptic", "greek",
-"marathi", "spanish",
-"american", "ancient", "australian", "british", "monotonic", "newzealand",
-"polytonic", 0};
-
-/**
- * the same as polyglossia_languages with .lyx names
- * please keep this in sync with polyglossia_languages line by line!
- */
-const char * const coded_polyglossia_languages[] = {
-"albanian", "croatian", "hebrew", "norsk", "swedish", "amharic", "czech", "hindi",
-"nynorsk", "syriac", "arabic_arabi", "danish", "icelandic", "occitan", "tamil",
-"armenian", "divehi", "interlingua", "polish", "telugu", "asturian", "dutch",
-"irish", "portuges", "thai", "bahasa", "english", "italian", "romanian", "turkish",
-"bahasam", "esperanto", "lao", "russian", "turkmen", "basque", "estonian", "latin",
-"samin", "ukrainian", "bengali", "farsi", "latvian", "sanskrit", "urdu", "brazilian",
-"brazilian", "finnish", "lithuanian", "scottish", "uppersorbian", "breton", "french",
-"lowersorbian", "serbian", "vietnamese", "bulgarian", "galician", "magyar", "slovak",
-"welsh", "catalan", "ngerman", "malayalam", "slovene", "coptic", "greek",
-"marathi", "spanish",
-"american", "ancientgreek", "australian", "british", "greek", "newzealand",
-"polutonikogreek", 0};
-
/**
* supported CJK encodings
+ * SJIS and Bg5 cannot be supported as they are not
+ * supported by iconv
+ * JIS does not work with LyX's encoding conversion
*/
const char * const supported_CJK_encodings[] = {
"EUC-JP", "KS", "GB", "UTF8", 0};
* the same as supported_CJK_encodings with their corresponding LyX language name
* please keep this in sync with supported_CJK_encodings line by line!
*/
-const char * const coded_supported_CJK_encodings[] = {
+const char * const supported_CJK_languages[] = {
"japanese-cjk", "korean", "chinese-simplified", "chinese-traditional", 0};
-string CJK2lyx(string const & encoding)
-{
- char const * const * where = is_known(encoding, supported_CJK_encodings);
- if (where)
- return coded_supported_CJK_encodings[where - supported_CJK_encodings];
- return encoding;
-}
-
/*!
* natbib commands.
* The starred forms are also known except for "citefullauthor",
}
context.check_deeper(os);
context.check_layout(os);
- unsigned int optargs = 0;
- while (optargs < context.layout->optargs) {
+ // FIXME: Adjust to format 446!
+ // Since format 446, layouts do not require anymore all optional
+ // arguments before the required ones. Needs to be implemented!
+ int optargs = 0;
+ while (optargs < context.layout->optArgs()) {
eat_whitespace(p, os, context, false);
if (p.next_token().cat() == catEscape ||
p.next_token().character() != '[')
break;
p.get_token(); // eat '['
- begin_inset(os, "Argument\n");
+ // FIXME: Just a workaround. InsetArgument::updateBuffer
+ // will compute a proper ID for all "999" Arguments
+ // (which is also what lyx2lyx produces).
+ // However, tex2lyx should be able to output proper IDs
+ // itself.
+ begin_inset(os, "Argument 999\n");
os << "status collapsed\n\n";
parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
end_inset(os);
eat_whitespace(p, os, context, false);
++optargs;
}
- unsigned int reqargs = 0;
- while (reqargs < context.layout->reqargs) {
+ int reqargs = 0;
+ while (reqargs < context.layout->requiredArgs()) {
eat_whitespace(p, os, context, false);
if (p.next_token().cat() != catBegin)
break;
p.get_token(); // eat '{'
- begin_inset(os, "Argument\n");
+ // FIXME: Just a workaround. InsetArgument::updateBuffer
+ // will compute a proper ID for all "999" Arguments
+ // (which is also what lyx2lyx produces).
+ // However, tex2lyx should be able to output proper IDs
+ // itself.
+ begin_inset(os, "Argument 999\n");
os << "status collapsed\n\n";
parse_text_in_inset(p, os, FLAG_BRACE_LAST, outer, context);
end_inset(os);
if (inner_type != "makebox") {
latex_height = p.getArg('[', ']');
translate_box_len(latex_height, height_value, height_unit, height_special);
- } else
- hor_pos = p.getArg('[', ']');
+ } else {
+ string const opt = p.getArg('[', ']');
+ if (!opt.empty()) {
+ hor_pos = opt;
+ if (hor_pos != "l" && hor_pos != "c" &&
+ hor_pos != "r" && hor_pos != "s") {
+ cerr << "invalid hor_pos " << hor_pos
+ << " for " << inner_type << endl;
+ hor_pos = "c";
+ }
+ }
+ }
if (p.hasOpt()) {
inner_pos = p.getArg('[', ']');
if (!opt.empty()) {
hor_pos = opt;
if (hor_pos != "l" && hor_pos != "c" &&
- hor_pos != "r") {
+ hor_pos != "r" && hor_pos != "s") {
cerr << "invalid hor_pos " << hor_pos
<< " for " << outer_type << endl;
hor_pos = "c";
if (p.hasOpt()) {
string arg = p.verbatimOption();
os << "lstparams " << '"' << arg << '"' << '\n';
+ if (arg.find("\\color") != string::npos)
+ preamble.registerAutomaticallyLoadedPackage("color");
}
if (in_line)
os << "inline true\n";
}
}
- else if (is_known(name, polyglossia_languages)) {
+ else if (is_known(name, preamble.polyglossia_languages)) {
// We must begin a new paragraph if not already done
if (! parent_context.atParagraphStart()) {
parent_context.check_end_layout(os);
}
// save the language in the context so that it is
// handled by parse_text
- parent_context.font.language = polyglossia2lyx(name);
+ parent_context.font.language = preamble.polyglossia2lyx(name);
parse_text(p, os, FLAG_END, outer, parent_context);
// Just in case the environment is empty
parent_context.extra_stuff.erase();
// store the encoding to be able to reset it
string const encoding_old = p.getEncoding();
string const encoding = p.getArg('{', '}');
- // SJIS and BIG5 don't work with LaTeX according to the comment in unicode.cpp
+ // SJIS and Bg5 cannot be handled by iconv
// JIS does not work with LyX's encoding conversion
- if (encoding != "SJIS" && encoding != "BIG5" && encoding != "JIS")
+ if (encoding != "Bg5" && encoding != "JIS" && encoding != "SJIS")
p.setEncoding(encoding);
else
p.setEncoding("utf8");
// LyX doesn't support the second argument so if
// this is used we need to output everything as ERT
string const mapping = p.getArg('{', '}');
- if ((!mapping.empty() && mapping != " ")
- || (!is_known(encoding, supported_CJK_encodings))) {
+ char const * const * const where =
+ is_known(encoding, supported_CJK_encodings);
+ if ((!mapping.empty() && mapping != " ") || !where) {
parent_context.check_layout(os);
handle_ert(os, "\\begin{" + name + "}{" + encoding + "}{" + mapping + "}",
parent_context);
- // we must parse the content as verbatim because e.g. SJIS can contain
+ // we must parse the content as verbatim because e.g. JIS can contain
// normally invalid characters
string const s = p.plainEnvironment("CJK");
for (string::const_iterator it = s.begin(), et = s.end(); it != et; ++it) {
else
os << *it;
}
- p.skip_spaces();
handle_ert(os, "\\end{" + name + "}",
parent_context);
} else {
- string const lang = CJK2lyx(encoding);
+ string const lang =
+ supported_CJK_languages[where - supported_CJK_encodings];
// store the language because we must reset it at the end
string const lang_old = parent_context.font.language;
parent_context.font.language = lang;
else if (name == "lstlisting") {
eat_whitespace(p, os, parent_context, false);
- // FIXME handle the automatic color package loading
- // uwestoehr asks: In what case color is loaded?
parse_listings(p, os, parent_context, false);
p.skip_spaces();
}
}
context.check_deeper(os);
// handle known optional and required arguments
- // layouts require all optional arguments before the required ones
+ // FIXME: Since format 446, layouts do not require anymore all optional
+ // arguments before the required ones. Needs to be implemented!
// Unfortunately LyX can't handle arguments of list arguments (bug 7468):
// It is impossible to place anything after the environment name,
// but before the first \\item.
if (context.layout->latextype == LATEX_ENVIRONMENT) {
bool need_layout = true;
- unsigned int optargs = 0;
- while (optargs < context.layout->optargs) {
+ int optargs = 0;
+ while (optargs < context.layout->optArgs()) {
eat_whitespace(p, os, context, false);
if (p.next_token().cat() == catEscape ||
p.next_token().character() != '[')
context.check_layout(os);
need_layout = false;
}
- begin_inset(os, "Argument\n");
+ // FIXME: Just a workaround. InsetArgument::updateBuffer
+ // will compute a proper ID for all "999" Arguments
+ // (which is also what lyx2lyx produces).
+ // However, tex2lyx should be able to output proper IDs
+ // itself.
+ begin_inset(os, "Argument 999\n");
os << "status collapsed\n\n";
parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
end_inset(os);
eat_whitespace(p, os, context, false);
++optargs;
}
- unsigned int reqargs = 0;
- while (reqargs < context.layout->reqargs) {
+ int reqargs = 0;
+ while (reqargs < context.layout->requiredArgs()) {
eat_whitespace(p, os, context, false);
if (p.next_token().cat() != catBegin)
break;
context.check_layout(os);
need_layout = false;
}
- begin_inset(os, "Argument\n");
+ // FIXME: Just a workaround. InsetArgument::updateBuffer
+ // will compute a proper ID for all "999" Arguments
+ // (which is also what lyx2lyx produces).
+ // However, tex2lyx should be able to output proper IDs
+ // itself.
+ begin_inset(os, "Argument 999\n");
os << "status collapsed\n\n";
parse_text_in_inset(p, os, FLAG_BRACE_LAST, outer, context);
end_inset(os);
/// Convert \p name from TeX convention (relative to master file) to LyX
/// convention (relative to .lyx file) if it is relative
-void fix_relative_filename(string & name)
+void fix_child_filename(string & name)
{
- if (FileName::isAbsolute(name))
- return;
+ string const absMasterTeX = getMasterFilePath(true);
+ bool const isabs = FileName::isAbsolute(name);
+ // convert from "relative to .tex master" to absolute original path
+ if (!isabs)
+ name = makeAbsPath(name, absMasterTeX).absFileName();
+ bool copyfile = copyFiles();
+ string const absParentLyX = getParentFilePath(false);
+ string abs = name;
+ if (copyfile) {
+ // convert from absolute original path to "relative to master file"
+ string const rel = to_utf8(makeRelPath(from_utf8(name),
+ from_utf8(absMasterTeX)));
+ // re-interpret "relative to .tex file" as "relative to .lyx file"
+ // (is different if the master .lyx file resides in a
+ // different path than the master .tex file)
+ string const absMasterLyX = getMasterFilePath(false);
+ abs = makeAbsPath(rel, absMasterLyX).absFileName();
+ // Do not copy if the new path is impossible to create. Example:
+ // absMasterTeX = "/foo/bar/"
+ // absMasterLyX = "/bar/"
+ // name = "/baz.eps" => new absolute name would be "/../baz.eps"
+ if (contains(name, "/../"))
+ copyfile = false;
+ }
+ if (copyfile) {
+ if (isabs)
+ name = abs;
+ else {
+ // convert from absolute original path to
+ // "relative to .lyx file"
+ name = to_utf8(makeRelPath(from_utf8(abs),
+ from_utf8(absParentLyX)));
+ }
+ }
+ else if (!isabs) {
+ // convert from absolute original path to "relative to .lyx file"
+ name = to_utf8(makeRelPath(from_utf8(name),
+ from_utf8(absParentLyX)));
+ }
+}
- name = to_utf8(makeRelPath(from_utf8(makeAbsPath(name, getMasterFilePath()).absFileName()),
- from_utf8(getParentFilePath())));
+
+void copy_file(FileName const & src, string dstname)
+{
+ if (!copyFiles())
+ return;
+ string const absParent = getParentFilePath(false);
+ FileName dst;
+ if (FileName::isAbsolute(dstname))
+ dst = FileName(dstname);
+ else
+ dst = makeAbsPath(dstname, absParent);
+ string const absMaster = getMasterFilePath(false);
+ FileName const srcpath = src.onlyPath();
+ FileName const dstpath = dst.onlyPath();
+ if (equivalent(srcpath, dstpath))
+ return;
+ if (!dstpath.isDirectory()) {
+ if (!dstpath.createPath()) {
+ cerr << "Warning: Could not create directory for file `"
+ << dst.absFileName() << "´." << endl;
+ return;
+ }
+ }
+ if (dst.isReadableFile()) {
+ if (overwriteFiles())
+ cerr << "Warning: Overwriting existing file `"
+ << dst.absFileName() << "´." << endl;
+ else {
+ cerr << "Warning: Not overwriting existing file `"
+ << dst.absFileName() << "´." << endl;
+ return;
+ }
+ }
+ if (!src.copyTo(dst))
+ cerr << "Warning: Could not copy file `" << src.absFileName()
+ << "´ to `" << dst.absFileName() << "´." << endl;
}
-/// Parse a NoWeb Scrap section. The initial "<<" is already parsed.
+/// Parse a NoWeb Chunk section. The initial "<<" is already parsed.
void parse_noweb(Parser & p, ostream & os, Context & context)
{
// assemble the rest of the keyword
string name("<<");
- bool scrap = false;
+ bool chunk = false;
while (p.good()) {
Token const & t = p.get_token();
if (t.asInput() == ">" && p.next_token().asInput() == ">") {
name += ">>";
p.get_token();
- scrap = (p.good() && p.next_token().asInput() == "=");
- if (scrap)
+ chunk = (p.good() && p.next_token().asInput() == "=");
+ if (chunk)
name += p.get_token().asInput();
break;
}
name += t.asInput();
}
- if (!scrap || !context.new_layout_allowed ||
- !context.textclass.hasLayout(from_ascii("Scrap"))) {
+ if (!chunk || !context.new_layout_allowed ||
+ !context.textclass.hasLayout(from_ascii("Chunk"))) {
cerr << "Warning: Could not interpret '" << name
<< "'. Ignoring it." << endl;
return;
// always must be in an own paragraph.
context.new_paragraph(os);
Context newcontext(true, context.textclass,
- &context.textclass[from_ascii("Scrap")]);
+ &context.textclass[from_ascii("Chunk")]);
newcontext.check_layout(os);
os << name;
while (p.good()) {
else {
ostringstream oss;
Context tmp(false, context.textclass,
- &context.textclass[from_ascii("Scrap")]);
+ &context.textclass[from_ascii("Chunk")]);
tmp.need_end_layout = true;
tmp.check_layout(oss);
os << subst(t.asInput(), "\n", oss.str());
}
- // The scrap chunk is ended by an @ at the beginning of a line.
+ // The chunk is ended by an @ at the beginning of a line.
// After the @ the line may contain a comment and/or
// whitespace, but nothing else.
if (t.asInput() == "@" && p.prev_token().cat() == catNewline &&
while (p.good()) {
Token const & t = p.get_token();
- // it is impossible to determine the correct document language if CJK is used.
- // Therefore write a note at the beginning of the document
- if (have_CJK) {
- context.check_layout(os);
- begin_inset(os, "Note Note\n");
- os << "status open\n\\begin_layout Plain Layout\n"
- << "\\series bold\n"
- << "Important information:\n"
- << "\\end_layout\n\n"
- << "\\begin_layout Plain Layout\n"
- << "This document contains text in Chinese, Japanese or Korean.\n"
- << " It was therefore impossible for tex2lyx to set the correct document langue for your document."
- << " Please set the language manually in the document settings.\n"
- << "\\end_layout\n";
- end_inset(os);
- have_CJK = false;
- }
-
// it is impossible to determine the correct encoding for non-CJK Japanese.
// Therefore write a note at the beginning of the document
if (is_nonCJKJapanese) {
skip_braces(p);
}
+ else if (t.asInput() == "<"
+ && p.next_token().asInput() == "<" && noweb_mode) {
+ p.get_token();
+ parse_noweb(p, os, context);
+ }
+
else if (t.asInput() == "<" && p.next_token().asInput() == "<") {
context.check_layout(os);
begin_inset(os, "Quotes ");
skip_braces(p);
}
- else if (t.asInput() == "<"
- && p.next_token().asInput() == "<" && noweb_mode) {
- p.get_token();
- parse_noweb(p, os, context);
- }
-
else if (t.cat() == catSpace || (t.cat() == catNewline && ! p.isParagraph()))
check_space(p, os, context);
skip_braces(p);
p.get_token();
string name = normalize_filename(p.verbatim_item());
- string const path = getMasterFilePath();
+ string const path = getMasterFilePath(true);
// We want to preserve relative / absolute filenames,
// therefore path is only used for testing
// The file extension is in every case ".tex".
if (!Gnumeric_name.empty())
name = Gnumeric_name;
}
- if (makeAbsPath(name, path).exists())
- fix_relative_filename(name);
- else
+ FileName const absname = makeAbsPath(name, path);
+ if (absname.exists()) {
+ fix_child_filename(name);
+ copy_file(absname, name);
+ } else
cerr << "Warning: Could not find file '"
<< name << "'." << endl;
context.check_layout(os);
end_inset(os);
context.check_layout(os);
macro = false;
- // register the packages that are automatically reloaded
+ // register the packages that are automatically loaded
// by the Gnumeric template
registerExternalTemplatePackages("GnumericSpreadsheet");
}
context.check_layout(os);
p.skip_spaces();
begin_inset(os, "Caption\n");
- Context newcontext(true, context.textclass);
- newcontext.font = context.font;
+ Context newcontext(true, context.textclass, 0, 0, context.font);
newcontext.check_layout(os);
+ // FIXME InsetArgument is now properly implemented in InsetLayout
+ // (for captions, but also for others)
if (p.next_token().cat() != catEscape &&
p.next_token().character() == '[') {
p.get_token(); // eat '['
- begin_inset(os, "Argument\n");
+ begin_inset(os, "Argument 1\n");
os << "status collapsed\n";
parse_text_in_inset(p, os, FLAG_BRACK_LAST, outer, context);
end_inset(os);
os << "\n\\begin_layout Plain Layout";
p.skip_spaces();
begin_inset(os, "Caption\n");
- Context newcontext(true, context.textclass);
- newcontext.font = context.font;
+ Context newcontext(true, context.textclass,
+ 0, 0, context.font);
newcontext.check_layout(os);
os << caption << "\n";
newcontext.check_end_layout(os);
opts["clip"] = string();
string name = normalize_filename(p.verbatim_item());
- string const path = getMasterFilePath();
+ string const path = getMasterFilePath(true);
// We want to preserve relative / absolute filenames,
// therefore path is only used for testing
if (!makeAbsPath(name, path).exists()) {
}
}
- if (makeAbsPath(name, path).exists())
- fix_relative_filename(name);
- else
+ FileName const absname = makeAbsPath(name, path);
+ if (absname.exists()) {
+ fix_child_filename(name);
+ copy_file(absname, name);
+ } else
cerr << "Warning: Could not find graphics file '"
<< name << "'." << endl;
else if (t.cs() == "href") {
context.check_layout(os);
- string target = p.getArg('{', '}');
- string name = p.getArg('{', '}');
+ string target = convert_command_inset_arg(p.verbatim_item());
+ string name = convert_command_inset_arg(p.verbatim_item());
string type;
size_t i = target.find(':');
if (i != string::npos) {
}
else if (prefixIs(t.cs(), "text")
- && is_known(t.cs().substr(4), polyglossia_languages)) {
+ && is_known(t.cs().substr(4), preamble.polyglossia_languages)) {
// scheme is \textLANGUAGE{text} where LANGUAGE is in polyglossia_languages[]
string lang;
// We have to output the whole command if it has an option
if (pos_var != string::npos && i == string::npos) {
string variant;
variant = langopts.substr(k + 1, langopts.length() - k - 2);
- lang = polyglossia2lyx(variant);
+ lang = preamble.polyglossia2lyx(variant);
parse_text_attributes(p, os, FLAG_ITEM, outer,
context, "\\lang",
context.font.language, lang);
} else
handle_ert(os, t.asInput() + langopts, context);
} else {
- lang = polyglossia2lyx(t.cs().substr(4, string::npos));
+ lang = preamble.polyglossia2lyx(t.cs().substr(4, string::npos));
parse_text_attributes(p, os, FLAG_ITEM, outer,
context, "\\lang",
context.font.language, lang);
else if (t.cs() == "verb") {
context.check_layout(os);
char const delimiter = p.next_token().character();
- string const arg = p.getArg(delimiter, delimiter);
+ // \verb is special: The usual escaping rules do not
+ // apply, e.g. "\verb+\+" is valid and denotes a single
+ // backslash (bug #4468). Therefore we do not allow
+ // escaping in getArg().
+ string const arg = p.getArg(delimiter, delimiter, false);
ostringstream oss;
oss << "\\verb" << delimiter << arg << delimiter;
handle_ert(os, oss.str(), context);
name += p.get_token().asInput();
context.check_layout(os);
string filename(normalize_filename(p.getArg('{', '}')));
- string const path = getMasterFilePath();
+ string const path = getMasterFilePath(true);
// We want to preserve relative / absolute filenames,
// therefore path is only used for testing
if ((t.cs() == "include" || t.cs() == "input") &&
if (makeAbsPath(filename, path).exists()) {
string const abstexname =
makeAbsPath(filename, path).absFileName();
- string const abslyxname =
- changeExtension(abstexname, ".lyx");
string const absfigname =
changeExtension(abstexname, ".fig");
- fix_relative_filename(filename);
+ fix_child_filename(filename);
string const lyxname =
changeExtension(filename, ".lyx");
+ string const abslyxname = makeAbsPath(
+ lyxname, getParentFilePath(false)).absFileName();
bool xfig = false;
- external = FileName(absfigname).exists();
- if (t.cs() == "input") {
+ if (!skipChildren())
+ external = FileName(absfigname).exists();
+ if (t.cs() == "input" && !skipChildren()) {
string const ext = getExtension(abstexname);
// Combined PS/LaTeX:
}
if (external) {
outname = changeExtension(filename, ".fig");
+ FileName abssrc(changeExtension(abstexname, ".fig"));
+ copy_file(abssrc, outname);
} else if (xfig) {
// Don't try to convert, the result
// would be full of ERT.
outname = filename;
+ FileName abssrc(abstexname);
+ copy_file(abssrc, outname);
} else if (t.cs() != "verbatiminput" &&
+ !skipChildren() &&
tex2lyx(abstexname, FileName(abslyxname),
p.getEncoding())) {
outname = lyxname;
+ // no need to call copy_file
+ // tex2lyx creates the file
} else {
outname = filename;
+ FileName abssrc(abstexname);
+ copy_file(abssrc, outname);
}
} else {
cerr << "Warning: Could not find included file '"
arg += p.getFullOpt();
eat_whitespace(p, os, context, false);
handle_ert(os, arg + '{', context);
- eat_whitespace(p, os, context, false);
parse_text(p, os, FLAG_ITEM, outer, context);
handle_ert(os, "}", context);
} else {
else {
eat_whitespace(p, os, context, false);
handle_ert(os, "\\framebox{", context);
- eat_whitespace(p, os, context, false);
parse_text(p, os, FLAG_ITEM, outer, context);
handle_ert(os, "}", context);
}
arg += p.getFullOpt();
eat_whitespace(p, os, context, false);
handle_ert(os, arg + '{', context);
- eat_whitespace(p, os, context, false);
parse_text(p, os, FLAG_ITEM, outer, context);
handle_ert(os, "}", context);
} else
vector<string> keys;
split_map(arg, opts, keys);
string name = normalize_filename(p.verbatim_item());
- string const path = getMasterFilePath();
+ string const path = getMasterFilePath(true);
// We want to preserve relative / absolute filenames,
// therefore path is only used for testing
if (!makeAbsPath(name, path).exists()) {
pdflatex = true;
}
}
- if (makeAbsPath(name, path).exists())
- fix_relative_filename(name);
- else
+ FileName const absname = makeAbsPath(name, path);
+ if (absname.exists())
+ {
+ fix_child_filename(name);
+ copy_file(absname, name);
+ } else
cerr << "Warning: Could not find file '"
<< name << "'." << endl;
// write output
else if (t.cs() == "loadgame") {
p.skip_spaces();
string name = normalize_filename(p.verbatim_item());
- string const path = getMasterFilePath();
+ string const path = getMasterFilePath(true);
// We want to preserve relative / absolute filenames,
// therefore path is only used for testing
if (!makeAbsPath(name, path).exists()) {
if (!lyxskak_name.empty())
name = lyxskak_name;
}
- if (makeAbsPath(name, path).exists())
- fix_relative_filename(name);
- else
+ FileName const absname = makeAbsPath(name, path);
+ if (absname.exists())
+ {
+ fix_child_filename(name);
+ copy_file(absname, name);
+ } else
cerr << "Warning: Could not find file '"
<< name << "'." << endl;
context.check_layout(os);
/*
string s = t.asInput();
string z = p.verbatim_item();
- while (p.good() && z != " " && z.size()) {
+ while (p.good() && z != " " && !z.empty()) {
//cerr << "read: " << z << endl;
s += z;
z = p.verbatim_item();
}
}
+
+string guessLanguage(Parser & p, string const & lang)
+{
+ typedef std::map<std::string, size_t> LangMap;
+ // map from language names to number of characters
+ LangMap used;
+ used[lang] = 0;
+ for (char const * const * i = supported_CJK_languages; *i; i++)
+ used[string(*i)] = 0;
+
+ while (p.good()) {
+ Token const t = p.get_token();
+ // comments are not counted for any language
+ if (t.cat() == catComment)
+ continue;
+ // commands are not counted as well, but we need to detect
+ // \begin{CJK} and switch encoding if needed
+ if (t.cat() == catEscape) {
+ if (t.cs() == "inputencoding") {
+ string const enc = subst(p.verbatim_item(), "\n", " ");
+ p.setEncoding(enc);
+ continue;
+ }
+ if (t.cs() != "begin")
+ continue;
+ } else {
+ // Non-CJK content is counted for lang.
+ // We do not care about the real language here:
+ // If we have more non-CJK contents than CJK contents,
+ // we simply use the language that was specified as
+ // babel main language.
+ used[lang] += t.asInput().length();
+ continue;
+ }
+ // Now we are starting an environment
+ p.pushPosition();
+ string const name = p.getArg('{', '}');
+ if (name != "CJK") {
+ p.popPosition();
+ continue;
+ }
+ // It is a CJK environment
+ p.popPosition();
+ /* name = */ p.getArg('{', '}');
+ string const encoding = p.getArg('{', '}');
+ /* mapping = */ p.getArg('{', '}');
+ string const encoding_old = p.getEncoding();
+ char const * const * const where =
+ is_known(encoding, supported_CJK_encodings);
+ if (where)
+ p.setEncoding(encoding);
+ else
+ p.setEncoding("utf8");
+ string const text = p.verbatimEnvironment("CJK");
+ p.setEncoding(encoding_old);
+ p.skip_spaces();
+ if (!where) {
+ // ignore contents in unknown CJK encoding
+ continue;
+ }
+ // the language of the text
+ string const cjk =
+ supported_CJK_languages[where - supported_CJK_encodings];
+ used[cjk] += text.length();
+ }
+ LangMap::const_iterator use = used.begin();
+ for (LangMap::const_iterator it = used.begin(); it != used.end(); ++it) {
+ if (it->second > use->second)
+ use = it;
+ }
+ return use->first;
+}
+
// }])