* Add native support for \includeonly (bug 5360).

File format change.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32826 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2010-01-07 10:01:26 +00:00
parent df2ad29d02
commit 1ccfe14914
10 changed files with 297 additions and 7 deletions

View File

@ -1,6 +1,15 @@
LyX file-format changes LyX file-format changes
----------------------- -----------------------
2010-01-06 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 375: add support for \includeonly
This adds a new buffer param list of relative filenames
which are output as \includeonly arguments, like this:
\begin_includeonly
child1.lyx
child2.lyx
\end_includeonly
2009-12-30 Richard Heck <rgheck@comcast.net> 2009-12-30 Richard Heck <rgheck@comcast.net>
* Format incremented to 374: add html output options. * Format incremented to 374: add html output options.
\html_use_mathml (boolean): whether to use MathML or images \html_use_mathml (boolean): whether to use MathML or images

View File

@ -940,6 +940,7 @@ src_frontends_qt4_ui_files = Split('''
ListingsSettingsUi.ui ListingsSettingsUi.ui
LogUi.ui LogUi.ui
MarginsUi.ui MarginsUi.ui
MasterChildUi.ui
MathMatrixUi.ui MathMatrixUi.ui
MathsUi.ui MathsUi.ui
ModulesUi.ui ModulesUi.ui

View File

@ -1141,6 +1141,19 @@ def revert_html_options(document):
del document.header[i] del document.header[i]
def revert_includeonly(document):
i = 0
while True:
i = find_token(document.header, "\\begin_includeonly", i)
if i == -1:
return
j = find_end_of(document.header, i, "\\begin_includeonly", "\\end_includeonly")
if j == -1:
# this should not happen
break
document.header[i : j + 1] = []
## ##
# Conversion hub # Conversion hub
# #
@ -1174,10 +1187,12 @@ convert = [[346, []],
[371, []], [371, []],
[372, []], [372, []],
[373, [merge_gbrief]], [373, [merge_gbrief]],
[374, []] [374, []],
[375, []]
] ]
revert = [[373, [revert_html_options]], revert = [[374, [revert_includeonly]],
[373, [revert_html_options]],
[372, [revert_gbrief]], [372, [revert_gbrief]],
[371, [revert_fontenc]], [371, [revert_fontenc]],
[370, [revert_mhchem]], [370, [revert_mhchem]],

View File

@ -127,7 +127,7 @@ namespace {
// Do not remove the comment below, so we get merge conflict in // Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own. // independent branches. Instead add your own.
int const LYX_FORMAT = 374; // rgheck: HTML output options int const LYX_FORMAT = 375; // jspitzm: includeonly support
typedef map<string, bool> DepClean; typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache; typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@ -607,6 +607,7 @@ int Buffer::readHeader(Lexer & lex)
params().listings_params.clear(); params().listings_params.clear();
params().clearLayoutModules(); params().clearLayoutModules();
params().clearRemovedModules(); params().clearRemovedModules();
params().clearIncludedChildren();
params().pdfoptions().clear(); params().pdfoptions().clear();
params().indiceslist().clear(); params().indiceslist().clear();
params().backgroundcolor = lyx::rgbFromHexName("#ffffff"); params().backgroundcolor = lyx::rgbFromHexName("#ffffff");
@ -1259,7 +1260,9 @@ void Buffer::writeLaTeXSource(odocstream & os,
listParentMacros(parentMacros, features); listParentMacros(parentMacros, features);
// Write the preamble // Write the preamble
runparams.use_babel = params().writeLaTeX(os, features, d->texrow); runparams.use_babel = params().writeLaTeX(os, features,
d->texrow,
d->filename.onlyPath());
runparams.use_japanese = features.isRequired("japanese"); runparams.use_japanese = features.isRequired("japanese");

View File

@ -536,6 +536,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
readModules(lex); readModules(lex);
} else if (token == "\\begin_removed_modules") { } else if (token == "\\begin_removed_modules") {
readRemovedModules(lex); readRemovedModules(lex);
} else if (token == "\\begin_includeonly") {
readIncludeonly(lex);
} else if (token == "\\options") { } else if (token == "\\options") {
lex.eatLine(); lex.eatLine();
options = lex.getString(); options = lex.getString();
@ -834,7 +836,17 @@ void BufferParams::writeFile(ostream & os) const
os << *it << '\n'; os << *it << '\n';
os << "\\end_modules" << '\n'; os << "\\end_modules" << '\n';
} }
// includeonly
if (!includedChildren_.empty()) {
os << "\\begin_includeonly" << '\n';
list<string>::const_iterator it = includedChildren_.begin();
list<string>::const_iterator en = includedChildren_.end();
for (; it != en; it++)
os << *it << '\n';
os << "\\end_includeonly" << '\n';
}
// local layout information // local layout information
if (!local_layout.empty()) { if (!local_layout.empty()) {
// remove '\n' from the end // remove '\n' from the end
@ -1080,7 +1092,7 @@ void BufferParams::validate(LaTeXFeatures & features) const
bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
TexRow & texrow) const TexRow & texrow, FileName const & filepath) const
{ {
os << "\\documentclass"; os << "\\documentclass";
@ -1249,6 +1261,31 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
// handle inputenc etc. // handle inputenc etc.
writeEncodingPreamble(os, features, texrow); writeEncodingPreamble(os, features, texrow);
// includeonly
if (!includedChildren_.empty()) {
os << "\\includeonly{";
list<string>::const_iterator it = includedChildren_.begin();
bool first = true;
for (; it != includedChildren_.end() ; ++it) {
string incfile = *it;
FileName inc = makeAbsPath(incfile, filepath.absFilename());
string mangled = DocFileName(changeExtension(inc.absFilename(), ".tex")).
mangledFilename();
if (!features.runparams().nice)
incfile = mangled;
// \includeonly doesn't want an extension
incfile = changeExtension(incfile, string());
incfile = latex_path(incfile);
if (!incfile.empty()) {
if (!first)
os << ",";
os << from_utf8(incfile);
}
first = false;
}
os << "}\n";
}
if (!listings_params.empty() || features.isRequired("listings")) { if (!listings_params.empty() || features.isRequired("listings")) {
os << "\\usepackage{listings}\n"; os << "\\usepackage{listings}\n";
texrow.newline(); texrow.newline();
@ -1903,6 +1940,23 @@ void BufferParams::readRemovedModules(Lexer & lex)
} }
void BufferParams::readIncludeonly(Lexer & lex)
{
if (!lex.eatLine()) {
lyxerr << "Error (BufferParams::readIncludeonly):"
"Unexpected end of input." << endl;
return;
}
while (true) {
string child = lex.getString();
if (child == "\\end_includeonly")
break;
includedChildren_.push_back(child);
lex.eatLine();
}
}
string BufferParams::paperSizeName(PapersizePurpose purpose) const string BufferParams::paperSizeName(PapersizePurpose purpose) const
{ {
char real_papersize = papersize; char real_papersize = papersize;

View File

@ -23,6 +23,7 @@
#include "insets/InsetQuotes.h" #include "insets/InsetQuotes.h"
#include "support/copied_ptr.h" #include "support/copied_ptr.h"
#include "support/FileName.h"
#include <list> #include <list>
#include <map> #include <map>
@ -84,7 +85,8 @@ public:
* the BufferParams and a LyXRC variable). * the BufferParams and a LyXRC variable).
* This returned value can then be passed to the insets... * This returned value can then be passed to the insets...
*/ */
bool writeLaTeX(odocstream &, LaTeXFeatures &, TexRow &) const; bool writeLaTeX(odocstream &, LaTeXFeatures &, TexRow &,
support::FileName const &) const;
/// ///
void useClassDefaults(); void useClassDefaults();
@ -154,6 +156,15 @@ public:
/// Clear the removed module list /// Clear the removed module list
void clearRemovedModules() { removedModules_.clear(); } void clearRemovedModules() { removedModules_.clear(); }
/// List of included children (for includeonly)
std::list<std::string> const & getIncludedChildren() const
{ return includedChildren_; }
///
void addIncludedChildren(std::string const & child)
{ includedChildren_.push_back(child); }
/// Clear the list of included children
void clearIncludedChildren() { includedChildren_.clear(); }
/// returns the main font for the buffer (document) /// returns the main font for the buffer (document)
Font const getFont() const; Font const getFont() const;
@ -384,6 +395,8 @@ private:
void readModules(Lexer &); void readModules(Lexer &);
/// ///
void readRemovedModules(Lexer &); void readRemovedModules(Lexer &);
///
void readIncludeonly(Lexer &);
/// for use with natbib /// for use with natbib
CiteEngine cite_engine_; CiteEngine cite_engine_;
/// ///
@ -394,6 +407,9 @@ private:
/// the user has chosen not to use /// the user has chosen not to use
std::list<std::string> removedModules_; std::list<std::string> removedModules_;
/// the list of included children (for includeonly)
std::list<std::string> includedChildren_;
/** Use the Pimpl idiom to hide those member variables that would otherwise /** Use the Pimpl idiom to hide those member variables that would otherwise
* drag in other header files. * drag in other header files.
*/ */

View File

@ -617,6 +617,23 @@ GuiDocument::GuiDocument(GuiView & lv)
bc().addCheckedLineEdit(textLayoutModule->indentLE); bc().addCheckedLineEdit(textLayoutModule->indentLE);
bc().addCheckedLineEdit(textLayoutModule->skipLE); bc().addCheckedLineEdit(textLayoutModule->skipLE);
// master/child handling
masterChildModule = new UiWidget<Ui::MasterChildUi>;
connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
masterChildModule->childrenTW, SLOT(setEnabled(bool)));
connect(masterChildModule->includeallRB, SIGNAL(clicked()),
this, SLOT(change_adaptor()));
connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
this, SLOT(change_adaptor()));
masterChildModule->childrenTW->setColumnCount(2);
masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
masterChildModule->childrenTW->resizeColumnToContents(1);
masterChildModule->childrenTW->resizeColumnToContents(2);
// output // output
outputModule = new UiWidget<Ui::OutputUi>; outputModule = new UiWidget<Ui::OutputUi>;
@ -1065,6 +1082,7 @@ GuiDocument::GuiDocument(GuiView & lv)
qt_("Input listings parameters below. Enter ? for a list of parameters.")); qt_("Input listings parameters below. Enter ? for a list of parameters."));
docPS->addPanel(latexModule, qt_("Document Class")); docPS->addPanel(latexModule, qt_("Document Class"));
docPS->addPanel(masterChildModule, qt_("Child Documents"));
docPS->addPanel(modulesModule, qt_("Modules")); docPS->addPanel(modulesModule, qt_("Modules"));
docPS->addPanel(fontModule, qt_("Fonts")); docPS->addPanel(fontModule, qt_("Fonts"));
docPS->addPanel(textLayoutModule, qt_("Text Layout")); docPS->addPanel(textLayoutModule, qt_("Text Layout"));
@ -1115,6 +1133,26 @@ void GuiDocument::change_adaptor()
} }
void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
{
if (item == 0)
return;
string child = fromqstr(item->text(0));
if (child.empty())
return;
if (std::find(includeonlys_.begin(),
includeonlys_.end(), child) != includeonlys_.end())
includeonlys_.remove(child);
else
includeonlys_.push_back(child);
updateIncludeonlys();
changed();
}
QString GuiDocument::validateListingsParameters() QString GuiDocument::validateListingsParameters()
{ {
// use a cache here to avoid repeated validation // use a cache here to avoid repeated validation
@ -1805,6 +1843,15 @@ void GuiDocument::updateDefaultFormat()
} }
bool GuiDocument::isChildIncluded(string const & child)
{
if (includeonlys_.empty())
return false;
return (std::find(includeonlys_.begin(),
includeonlys_.end(), child) != includeonlys_.end());
}
void GuiDocument::applyView() void GuiDocument::applyView()
{ {
// preamble // preamble
@ -2043,6 +2090,15 @@ void GuiDocument::applyView()
else else
bp_.master = string(); bp_.master = string();
// Master/Child
bp_.clearIncludedChildren();
if (masterChildModule->includeonlyRB->isChecked()) {
list<string>::const_iterator it = includeonlys_.begin();
for (; it != includeonlys_.end() ; ++it) {
bp_.addIncludedChildren(*it);
}
}
// Float Placement // Float Placement
bp_.float_placement = floatModule->get(); bp_.float_placement = floatModule->get();
@ -2422,6 +2478,17 @@ void GuiDocument::paramsToDialog()
latexModule->childDocGB->setChecked(false); latexModule->childDocGB->setChecked(false);
} }
// Master/Child
std::vector<Buffer *> children = buffer().getChildren(false);
if (children.empty()) {
masterChildModule->setEnabled(false);
includeonlys_.clear();
} else {
masterChildModule->setEnabled(true);
includeonlys_ = bp_.getIncludedChildren();
updateIncludeonlys();
}
// Float Settings // Float Settings
floatModule->set(bp_.float_placement); floatModule->set(bp_.float_placement);
@ -2649,6 +2716,52 @@ void GuiDocument::updateSelectedModules()
} }
void GuiDocument::updateIncludeonlys()
{
masterChildModule->childrenTW->clear();
QString const no = qt_("No");
QString const yes = qt_("Yes");
if (includeonlys_.empty()) {
masterChildModule->includeallRB->setChecked(true);
masterChildModule->childrenTW->setEnabled(false);
} else {
masterChildModule->includeonlyRB->setChecked(true);
masterChildModule->childrenTW->setEnabled(true);
}
QTreeWidgetItem * item = 0;
std::vector<Buffer *> children = buffer().getChildren(false);
vector<Buffer *>::const_iterator it = children.begin();
vector<Buffer *>::const_iterator end = children.end();
bool has_unincluded = false;
bool all_unincluded = true;
for (; it != end; ++it) {
item = new QTreeWidgetItem(masterChildModule->childrenTW);
// FIXME Unicode
string const name =
to_utf8(makeRelPath(from_utf8((*it)->fileName().absFilename()),
from_utf8(buffer().filePath())));
item->setText(0, toqstr(name));
item->setText(1, isChildIncluded(name) ? yes : no);
if (!isChildIncluded(name))
has_unincluded = true;
else
all_unincluded = false;
}
// Both if all childs are included and if none is included
// is equal to "include all" (i.e., ommit \includeonly).
// Thus, reset the GUI.
if (!has_unincluded || all_unincluded) {
masterChildModule->includeallRB->setChecked(true);
masterChildModule->childrenTW->setEnabled(false);
includeonlys_.clear();
}
// If all are included, we need to update again.
if (!has_unincluded)
updateIncludeonlys();
}
void GuiDocument::updateContents() void GuiDocument::updateContents()
{ {
// Nothing to do here as the document settings is not cursor dependant. // Nothing to do here as the document settings is not cursor dependant.

View File

@ -23,6 +23,7 @@
#include "ui_DocumentUi.h" #include "ui_DocumentUi.h"
#include "ui_FontUi.h" #include "ui_FontUi.h"
#include "ui_TextLayoutUi.h" #include "ui_TextLayoutUi.h"
#include "ui_MasterChildUi.h"
#include "ui_MathsUi.h" #include "ui_MathsUi.h"
#include "ui_LaTeXUi.h" #include "ui_LaTeXUi.h"
#include "ui_PageLayoutUi.h" #include "ui_PageLayoutUi.h"
@ -75,6 +76,7 @@ public:
void updateFontlist(); void updateFontlist();
void updateDefaultFormat(); void updateDefaultFormat();
void updatePagestyle(std::string const &, std::string const &); void updatePagestyle(std::string const &, std::string const &);
bool isChildIncluded(std::string const &);
void showPreamble(); void showPreamble();
/// ///
@ -83,6 +85,7 @@ public:
private Q_SLOTS: private Q_SLOTS:
void updateNumbering(); void updateNumbering();
void change_adaptor(); void change_adaptor();
void includeonlyClicked(QTreeWidgetItem * item, int);
void setListingsMessage(); void setListingsMessage();
void saveDefaultClicked(); void saveDefaultClicked();
void useDefaultsClicked(); void useDefaultsClicked();
@ -115,6 +118,7 @@ private:
QString validateListingsParameters(); QString validateListingsParameters();
UiWidget<Ui::TextLayoutUi> *textLayoutModule; UiWidget<Ui::TextLayoutUi> *textLayoutModule;
UiWidget<Ui::MasterChildUi> *masterChildModule;
UiWidget<Ui::FontUi> *fontModule; UiWidget<Ui::FontUi> *fontModule;
UiWidget<Ui::PageLayoutUi> *pageLayoutModule; UiWidget<Ui::PageLayoutUi> *pageLayoutModule;
UiWidget<Ui::MarginsUi> *marginsModule; UiWidget<Ui::MarginsUi> *marginsModule;
@ -150,6 +154,8 @@ private:
void updateAvailableModules(); void updateAvailableModules();
/// ///
void updateSelectedModules(); void updateSelectedModules();
///
void updateIncludeonlys();
/// save as default template /// save as default template
void saveDocDefault(); void saveDocDefault();
/// reset to default params /// reset to default params
@ -232,6 +238,8 @@ private:
std::list<modInfoStruct> moduleNames_; std::list<modInfoStruct> moduleNames_;
/// ///
std::map<docstring, docstring> changedBranches_; std::map<docstring, docstring> changedBranches_;
///
std::list<std::string> includeonlys_;
}; };

View File

@ -282,6 +282,7 @@ UIFILES = \
ListingsSettingsUi.ui \ ListingsSettingsUi.ui \
LogUi.ui \ LogUi.ui \
MarginsUi.ui \ MarginsUi.ui \
MasterChildUi.ui \
MathMatrixUi.ui \ MathMatrixUi.ui \
MathsUi.ui \ MathsUi.ui \
ModulesUi.ui \ ModulesUi.ui \

View File

@ -0,0 +1,70 @@
<ui version="4.0" >
<class>MasterChildUi</class>
<widget class="QWidget" name="MasterChildUi" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>348</width>
<height>327</height>
</rect>
</property>
<property name="windowTitle" >
<string/>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QGroupBox" name="includeonlyGB" >
<property name="title" >
<string>Master Document Output</string>
</property>
<property name="flat" >
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QRadioButton" name="includeallRB" >
<property name="toolTip" >
<string>Include all included subdocuments in the output</string>
</property>
<property name="text" >
<string>&amp;Include all children</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QRadioButton" name="includeonlyRB" >
<property name="toolTip" >
<string>Include only the selected subdocuments in the output</string>
</property>
<property name="text" >
<string>Include &amp;only selected children</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QTreeWidget" name="childrenTW" />
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<includes>
<include location="local" >qt_i18n.h</include>
</includes>
<resources/>
<connections/>
</ui>