mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
tex2lyx: support for \includeonly
This commit is contained in:
parent
3d0ce01ff1
commit
15fd17d83f
@ -173,6 +173,11 @@ const char * const known_basic_color_codes[] = {"#000000", "#0000ff", "#964B00",
|
|||||||
const char * const known_if_3arg_commands[] = {"@ifundefined", "IfFileExists",
|
const char * const known_if_3arg_commands[] = {"@ifundefined", "IfFileExists",
|
||||||
0};
|
0};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Known file extensions for TeX files as used by \\includeonly
|
||||||
|
*/
|
||||||
|
char const * const known_tex_extensions[] = {"tex", 0};
|
||||||
|
|
||||||
/// packages that work only in xetex
|
/// packages that work only in xetex
|
||||||
/// polyglossia is handled separately
|
/// polyglossia is handled separately
|
||||||
const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
|
const char * const known_xetex_packages[] = {"arabxetex", "fixlatvian",
|
||||||
@ -1252,6 +1257,12 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
|
|||||||
os << *it << '\n';
|
os << *it << '\n';
|
||||||
os << "\\end_modules\n";
|
os << "\\end_modules\n";
|
||||||
}
|
}
|
||||||
|
if (!h_includeonlys.empty()) {
|
||||||
|
os << "\\begin_includeonly\n";
|
||||||
|
for (auto const & iofile : h_includeonlys)
|
||||||
|
os << iofile << '\n';
|
||||||
|
os << "\\end_includeonly\n";
|
||||||
|
}
|
||||||
os << "\\maintain_unincluded_children " << h_maintain_unincluded_children << "\n"
|
os << "\\maintain_unincluded_children " << h_maintain_unincluded_children << "\n"
|
||||||
<< "\\language " << h_language << "\n"
|
<< "\\language " << h_language << "\n"
|
||||||
<< "\\language_package " << h_language_package << "\n"
|
<< "\\language_package " << h_language_package << "\n"
|
||||||
@ -2040,6 +2051,33 @@ void Preamble::parse(Parser & p, string const & forceclass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t.cs() == "includeonly") {
|
||||||
|
vector<string> includeonlys = getVectorFromString(p.getArg('{', '}'));
|
||||||
|
for (auto & iofile : includeonlys) {
|
||||||
|
string filename(normalize_filename(iofile));
|
||||||
|
string const path = getMasterFilePath(true);
|
||||||
|
// We want to preserve relative/absolute filenames,
|
||||||
|
// therefore path is only used for testing
|
||||||
|
if (!makeAbsPath(filename, path).exists()) {
|
||||||
|
// The file extension is probably missing.
|
||||||
|
// Now try to find it out.
|
||||||
|
string const tex_name =
|
||||||
|
find_file(filename, path,
|
||||||
|
known_tex_extensions);
|
||||||
|
if (!tex_name.empty())
|
||||||
|
filename = tex_name;
|
||||||
|
}
|
||||||
|
string outname;
|
||||||
|
if (makeAbsPath(filename, path).exists())
|
||||||
|
fix_child_filename(filename);
|
||||||
|
else
|
||||||
|
cerr << "Warning: Could not find included file '"
|
||||||
|
<< filename << "'." << endl;
|
||||||
|
outname = changeExtension(filename, "lyx");
|
||||||
|
h_includeonlys.push_back(outname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (is_known(t.cs(), known_if_3arg_commands)) {
|
else if (is_known(t.cs(), known_if_3arg_commands)) {
|
||||||
// prevent misparsing of \usepackage if it is used
|
// prevent misparsing of \usepackage if it is used
|
||||||
// as an argument (see e.g. our own output of
|
// as an argument (see e.g. our own output of
|
||||||
|
@ -223,6 +223,7 @@ private:
|
|||||||
std::map<std::string, std::string> h_use_packages;
|
std::map<std::string, std::string> h_use_packages;
|
||||||
std::string h_use_default_options;
|
std::string h_use_default_options;
|
||||||
std::string h_use_hyperref;
|
std::string h_use_hyperref;
|
||||||
|
std::vector<std::string> h_includeonlys;
|
||||||
bool h_use_refstyle;
|
bool h_use_refstyle;
|
||||||
bool h_use_minted;
|
bool h_use_minted;
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ Format LaTeX feature LyX feature
|
|||||||
363 horizontal longtable alignment InsetTabular
|
363 horizontal longtable alignment InsetTabular
|
||||||
364 branch file name suffix \filename_suffix
|
364 branch file name suffix \filename_suffix
|
||||||
371 automatic mhchem loading \use_mhchem
|
371 automatic mhchem loading \use_mhchem
|
||||||
375 \includeonly \{begin,end}_includeonly
|
|
||||||
376 update .aux of unincluded children \maintain_unincluded_children
|
|
||||||
377 multirow.sty InsetTabular
|
377 multirow.sty InsetTabular
|
||||||
378 revision info InsetInfo
|
378 revision info InsetInfo
|
||||||
380 ? InsetPreview
|
380 ? InsetPreview
|
||||||
|
@ -51,6 +51,13 @@ void parse_text(Parser & p, std::ostream & os, unsigned flags, bool outer,
|
|||||||
Context & context);
|
Context & context);
|
||||||
void check_comment_bib(std::ostream & os, Context & context);
|
void check_comment_bib(std::ostream & os, Context & context);
|
||||||
|
|
||||||
|
void fix_child_filename(std::string & name);
|
||||||
|
|
||||||
|
std::string const normalize_filename(std::string const & name);
|
||||||
|
|
||||||
|
std::string find_file(std::string const & name, std::string const & path,
|
||||||
|
char const * const * extensions);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Parses a subdocument, usually useful in insets (whence the name).
|
* Parses a subdocument, usually useful in insets (whence the name).
|
||||||
*
|
*
|
||||||
|
@ -482,22 +482,6 @@ void translate_box_len(string const & length, string & value, string & unit, str
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Find a file with basename \p name in path \p path and an extension
|
|
||||||
* in \p extensions.
|
|
||||||
*/
|
|
||||||
string find_file(string const & name, string const & path,
|
|
||||||
char const * const * extensions)
|
|
||||||
{
|
|
||||||
for (char const * const * what = extensions; *what; ++what) {
|
|
||||||
string const trial = addExtension(name, *what);
|
|
||||||
if (makeAbsPath(trial, path).exists())
|
|
||||||
return trial;
|
|
||||||
}
|
|
||||||
return string();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void begin_inset(ostream & os, string const & name)
|
void begin_inset(ostream & os, string const & name)
|
||||||
{
|
{
|
||||||
os << "\n\\begin_inset " << name;
|
os << "\n\\begin_inset " << name;
|
||||||
@ -2194,96 +2178,6 @@ void get_cite_arguments(Parser & p, bool natbibOrder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Convert filenames with TeX macros and/or quotes to something LyX
|
|
||||||
/// can understand
|
|
||||||
string const normalize_filename(string const & name)
|
|
||||||
{
|
|
||||||
Parser p(name);
|
|
||||||
ostringstream os;
|
|
||||||
while (p.good()) {
|
|
||||||
Token const & t = p.get_token();
|
|
||||||
if (t.cat() != catEscape)
|
|
||||||
os << t.asInput();
|
|
||||||
else if (t.cs() == "lyxdot") {
|
|
||||||
// This is used by LyX for simple dots in relative
|
|
||||||
// names
|
|
||||||
os << '.';
|
|
||||||
p.skip_spaces();
|
|
||||||
} else if (t.cs() == "space") {
|
|
||||||
os << ' ';
|
|
||||||
p.skip_spaces();
|
|
||||||
} else if (t.cs() == "string") {
|
|
||||||
// Convert \string" to " and \string~ to ~
|
|
||||||
Token const & n = p.next_token();
|
|
||||||
if (n.asInput() != "\"" && n.asInput() != "~")
|
|
||||||
os << t.asInput();
|
|
||||||
} else
|
|
||||||
os << t.asInput();
|
|
||||||
}
|
|
||||||
// Strip quotes. This is a bit complicated (see latex_path()).
|
|
||||||
string full = os.str();
|
|
||||||
if (!full.empty() && full[0] == '"') {
|
|
||||||
string base = removeExtension(full);
|
|
||||||
string ext = getExtension(full);
|
|
||||||
if (!base.empty() && base[base.length()-1] == '"')
|
|
||||||
// "a b"
|
|
||||||
// "a b".tex
|
|
||||||
return addExtension(trim(base, "\""), ext);
|
|
||||||
if (full[full.length()-1] == '"')
|
|
||||||
// "a b.c"
|
|
||||||
// "a b.c".tex
|
|
||||||
return trim(full, "\"");
|
|
||||||
}
|
|
||||||
return full;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert \p name from TeX convention (relative to master file) to LyX
|
|
||||||
/// convention (relative to .lyx file) if it is relative
|
|
||||||
void fix_child_filename(string & name)
|
|
||||||
{
|
|
||||||
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)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void copy_file(FileName const & src, string dstname)
|
void copy_file(FileName const & src, string dstname)
|
||||||
{
|
{
|
||||||
if (!copyFiles())
|
if (!copyFiles())
|
||||||
@ -2508,6 +2402,112 @@ void registerExternalTemplatePackages(string const & name)
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Find a file with basename \p name in path \p path and an extension
|
||||||
|
* in \p extensions.
|
||||||
|
*/
|
||||||
|
string find_file(string const & name, string const & path,
|
||||||
|
char const * const * extensions)
|
||||||
|
{
|
||||||
|
for (char const * const * what = extensions; *what; ++what) {
|
||||||
|
string const trial = addExtension(name, *what);
|
||||||
|
if (makeAbsPath(trial, path).exists())
|
||||||
|
return trial;
|
||||||
|
}
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Convert filenames with TeX macros and/or quotes to something LyX
|
||||||
|
/// can understand
|
||||||
|
string const normalize_filename(string const & name)
|
||||||
|
{
|
||||||
|
Parser p(name);
|
||||||
|
ostringstream os;
|
||||||
|
while (p.good()) {
|
||||||
|
Token const & t = p.get_token();
|
||||||
|
if (t.cat() != catEscape)
|
||||||
|
os << t.asInput();
|
||||||
|
else if (t.cs() == "lyxdot") {
|
||||||
|
// This is used by LyX for simple dots in relative
|
||||||
|
// names
|
||||||
|
os << '.';
|
||||||
|
p.skip_spaces();
|
||||||
|
} else if (t.cs() == "space") {
|
||||||
|
os << ' ';
|
||||||
|
p.skip_spaces();
|
||||||
|
} else if (t.cs() == "string") {
|
||||||
|
// Convert \string" to " and \string~ to ~
|
||||||
|
Token const & n = p.next_token();
|
||||||
|
if (n.asInput() != "\"" && n.asInput() != "~")
|
||||||
|
os << t.asInput();
|
||||||
|
} else
|
||||||
|
os << t.asInput();
|
||||||
|
}
|
||||||
|
// Strip quotes. This is a bit complicated (see latex_path()).
|
||||||
|
string full = os.str();
|
||||||
|
if (!full.empty() && full[0] == '"') {
|
||||||
|
string base = removeExtension(full);
|
||||||
|
string ext = getExtension(full);
|
||||||
|
if (!base.empty() && base[base.length()-1] == '"')
|
||||||
|
// "a b"
|
||||||
|
// "a b".tex
|
||||||
|
return addExtension(trim(base, "\""), ext);
|
||||||
|
if (full[full.length()-1] == '"')
|
||||||
|
// "a b.c"
|
||||||
|
// "a b.c".tex
|
||||||
|
return trim(full, "\"");
|
||||||
|
}
|
||||||
|
return full;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Convert \p name from TeX convention (relative to master file) to LyX
|
||||||
|
/// convention (relative to .lyx file) if it is relative
|
||||||
|
void fix_child_filename(string & name)
|
||||||
|
{
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
|
||||||
Context & context)
|
Context & context)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user