LyX file-format changes
-----------------------
+2009-04-15 Jürgen Spitzmüller <spitz@lyx.org>
+ * Format incremented to 352: splitindex support.
+
2009-04-11 Uwe Stöhr <uwestoehr@web.de>
* Format incremented to 351: support to set a page background color.
FuncRequest.h
FuncStatus.h
Graph.h
+ IndicesList.h
InsetIterator.h
InsetList.h
Intl.h
FuncRequest.cpp
FuncStatus.cpp
Graph.cpp
+ IndicesList.cpp
InsetIterator.cpp
InsetList.cpp
Intl.cpp
GuiIdListModel.h
GuiImage.h
GuiInclude.h
+ GuiIndices.h
GuiInfo.h
GuiKeySymbol.h
GuiLabel.h
GuiIdListModel.cpp
GuiImage.cpp
GuiInclude.cpp
+ GuiIndices.cpp
GuiInfo.cpp
GuiKeySymbol.cpp
GuiLabel.cpp
HSpaceUi.ui
HyperlinkUi.ui
IncludeUi.ui
+ IndicesUi.ui
InfoUi.ui
LabelUi.ui
LaTeXUi.ui
\TestPackage{setspace}
\TestPackage{slashed}
\TestPackage{soul}
+\TestPackage{splitidx}
\TestPackage{subfig}
\TestPackage{textcomp}
\TestPackage{ulem}
rc_entry = [ r'\index_command "%%"' ])
checkProg('an index processor appropriate to Japanese', ['mendex -c -q', 'makeindex -c -q'],
rc_entry = [ r'\jindex_command "%%"' ])
+ checkProg('the splitindex processor', ['splitindex.pl', 'java splitindex', 'splitindex'],
+ rc_entry = [ r'\splitindex_command "%%"' ])
checkProg('a nomenclature processor', ['makeindex'],
rc_entry = [ r'\nomencl_command "makeindex -s nomencl.ist"' ])
## FIXME: OCTAVE is not used anywhere
#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/
-\lyxformat 347
+\lyxformat 352
\begin_document
\begin_header
\textclass article
\font_sans default
\font_typewriter default
\font_default_family default
+\use_xetex false
\font_sc false
\font_osf false
\font_sf_scale 100
\font_tt_scale 100
\graphics default
+\default_output_format default
\paperfontsize default
\spacing single
\use_hyperref false
\use_esint 0
\cite_engine basic
\use_bibtopic false
+\use_indices false
\paperorientation portrait
+\backgroundcolor #ffffff
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
is needed by LyX to correctly typeset unicode symbols with slashes in math.
\end_layout
+\begin_layout Subsection
+splitidx
+\end_layout
+
+\begin_layout Description
+Found:
+\begin_inset Info
+type "package"
+arg "splitidx"
+\end_inset
+
+
+\end_layout
+
+\begin_layout Description
+CTAN:
+\family typewriter
+macros/latex/contrib/splitindex/
+\end_layout
+
+\begin_layout Description
+Notes: The package
+\family sans
+splitidx
+\family default
+ is needed by LyX to generate multiple and subdivided indices.
+ Note that you also need to install one of the included
+\family sans
+splitindex
+\family default
+ converter programs.
+\end_layout
+
\begin_layout Subsection
subfig
\end_layout
""" Convert files to the file format generated by lyx 2.0"""
import re, string
+import unicodedata
+import sys, os
from parser_tools import find_token, find_end_of, find_tokens, get_value, get_value_string
document.preamble.insert(index, text)
+def read_unicodesymbols():
+ " Read the unicodesymbols list of unicode characters and corresponding commands."
+ pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
+ fp = open(os.path.join(pathname.strip('lyx2lyx'), 'unicodesymbols'))
+ spec_chars = []
+ # Two backslashes, followed by some non-word character, and then a character
+ # in brackets. The idea is to check for constructs like: \"{u}, which is how
+ # they are written in the unicodesymbols file; but they can also be written
+ # as: \"u or even \" u.
+ r = re.compile(r'\\\\(\W)\{(\w)\}')
+ for line in fp.readlines():
+ if line[0] != '#' and line.strip() != "":
+ line=line.replace(' "',' ') # remove all quotation marks with spaces before
+ line=line.replace('" ',' ') # remove all quotation marks with spaces after
+ line=line.replace(r'\"','"') # replace \" by " (for characters with diaeresis)
+ try:
+ [ucs4,command,dead] = line.split(None,2)
+ if command[0:1] != "\\":
+ continue
+ spec_chars.append([command, unichr(eval(ucs4))])
+ except:
+ continue
+ m = r.match(command)
+ if m != None:
+ command = "\\\\"
+ # If the character is a double-quote, then we need to escape it, too,
+ # since it is done that way in the LyX file.
+ if m.group(1) == "\"":
+ command += "\\"
+ commandbl = command
+ command += m.group(1) + m.group(2)
+ commandbl += m.group(1) + ' ' + m.group(2)
+ spec_chars.append([command, unichr(eval(ucs4))])
+ spec_chars.append([commandbl, unichr(eval(ucs4))])
+ fp.close()
+ return spec_chars
+
+
+unicode_reps = read_unicodesymbols()
+
+
+def put_cmd_in_ert(string):
+ for rep in unicode_reps:
+ string = string.replace(rep[1], rep[0].replace('\\\\', '\\'))
+ string = string.replace('\\', "\\backslash\n")
+ string = "\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n" \
+ + string + "\n\\end_layout\n\\end_inset"
+ return string
+
+
+def lyx2latex(document, lines):
+ 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'
+ # clean up multiline stuff
+ content = ""
+ ert_end = 0
+
+ for curline in range(len(lines)):
+ line = lines[curline]
+ if line.startswith("\\begin_inset ERT"):
+ # We don't want to replace things inside ERT, so figure out
+ # where the end of the inset is.
+ ert_end = find_end_of_inset(lines, curline + 1)
+ continue
+ elif line.startswith("\\begin_inset Formula"):
+ line = line[20:]
+ elif line.startswith("\\begin_inset Quotes"):
+ # For now, we do a very basic reversion. Someone who understands
+ # quotes is welcome to fix it up.
+ qtype = line[20:].strip()
+ # lang = qtype[0]
+ side = qtype[1]
+ dbls = qtype[2]
+ if side == "l":
+ if dbls == "d":
+ line = "``"
+ else:
+ line = "`"
+ else:
+ if dbls == "d":
+ line = "''"
+ else:
+ line = "'"
+ elif line.isspace() or \
+ line.startswith("\\begin_layout") or \
+ line.startswith("\\end_layout") or \
+ line.startswith("\\begin_inset") or \
+ line.startswith("\\end_inset") or \
+ line.startswith("\\lang") or \
+ line.strip() == "status collapsed" or \
+ line.strip() == "status open":
+ #skip all that stuff
+ continue
+
+ # this needs to be added to the preamble because of cases like
+ # \textmu, \textbackslash, etc.
+ add_to_preamble(document, ['% added by lyx2lyx for converted index entries',
+ '\\@ifundefined{textmu}',
+ ' {\\usepackage{textcomp}}{}'])
+ # a lossless reversion is not possible
+ # try at least to handle some common insets and settings
+ if ert_end >= curline:
+ line = line.replace(r'\backslash', r'\\')
+ else:
+ line = line.replace('&', '\\&{}')
+ line = line.replace('#', '\\#{}')
+ line = line.replace('^', '\\^{}')
+ line = line.replace('%', '\\%{}')
+ line = line.replace('_', '\\_{}')
+ line = line.replace('$', '\\${}')
+
+ # Do the LyX text --> LaTeX conversion
+ for rep in unicode_reps:
+ line = line.replace(rep[1], rep[0] + "{}")
+ line = line.replace(r'\backslash', r'\textbackslash{}')
+ line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
+ line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
+ line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
+ line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
+ line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
+ line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
+ line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
+ line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
+ line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
+ content += line
+ return content
+
+
####################################################################
def revert_backgroundcolor(document):
- " Reverts backgrund color to preamble code "
+ " Reverts background color to preamble code "
i = 0
colorcode = ""
while True:
+ '\\pagecolor{page_backgroundcolor}\n')
+def revert_splitindex(document):
+ " Reverts splitindex-aware documents "
+ i = find_token(document.header, '\\use_indices', 0)
+ if i == -1:
+ document.warning("Malformed LyX document: Missing \\use_indices.")
+ return
+ indices = get_value(document.header, "\\use_indices", i)
+ preamble = ""
+ if indices == "true":
+ preamble += "\\usepackage{splitidx}\n"
+ del document.header[i]
+ i = 0
+ while True:
+ i = find_token(document.header, "\\index", i)
+ if i == -1:
+ break
+ k = find_token(document.header, "\\end_index", i)
+ if k == -1:
+ document.warning("Malformed LyX document: Missing \\end_index.")
+ return
+ line = document.header[i]
+ l = re.compile(r'\\index (.*)$')
+ m = l.match(line)
+ iname = m.group(1)
+ ishortcut = get_value(document.header, '\\shortcut', i, k)
+ if ishortcut != "" and indices == "true":
+ preamble += "\\newindex[" + iname + "]{" + ishortcut + "}\n"
+ del document.header[i:k+1]
+ i = 0
+ if preamble != "":
+ insert_to_preamble(0, document, preamble)
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Index", i)
+ if i == -1:
+ break
+ line = document.body[i]
+ l = re.compile(r'\\begin_inset Index (.*)$')
+ m = l.match(line)
+ itype = m.group(1)
+ if itype == "idx" or indices == "false":
+ document.body[i] = "\\begin_inset Index"
+ else:
+ k = find_end_of_inset(document.body, i)
+ if k == -1:
+ return
+ content = lyx2latex(document, document.body[i:k])
+ # escape quotes
+ content = content.replace('"', r'\"')
+ subst = [put_cmd_in_ert("\\sindex[" + itype + "]{" + content + "}")]
+ document.body[i:k+1] = subst
+ i = i + 1
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset index_print", i)
+ if i == -1:
+ return
+ k = find_end_of_inset(document.body, i)
+ ptype = get_value(document.body, 'type', i, k).strip('"')
+ if ptype == "idx":
+ j = find_token(document.body, "type", i, k)
+ del document.body[j]
+ elif indices == "false":
+ del document.body[i:k+1]
+ else:
+ subst = [put_cmd_in_ert("\\printindex[" + ptype + "]{}")]
+ document.body[i:k+1] = subst
+ i = i + 1
+
+
+def convert_splitindex(document):
+ " Converts index and printindex insets to splitindex-aware format "
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Index", i)
+ if i == -1:
+ break
+ document.body[i] = document.body[i].replace("\\begin_inset Index",
+ "\\begin_inset Index idx")
+ i = i + 1
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset CommandInset index_print", i)
+ if i == -1:
+ return
+ if document.body[i + 1].find('LatexCommand printindex') == -1:
+ document.warning("Malformed LyX document: Incomplete printindex inset.")
+ return
+ subst = ["LatexCommand printindex",
+ "type \"idx\""]
+ document.body[i + 1:i + 2] = subst
+ i = i + 1
+
+
##
# Conversion hub
#
[348, []],
[349, []],
[350, []],
- [351, []]
+ [351, []],
+ [352, [convert_splitindex]]
]
-revert = [[350, [revert_backgroundcolor]],
+revert = [[351, [revert_splitindex]],
+ [350, [revert_backgroundcolor]],
[349, [revert_outputformat]],
[348, [revert_xetex]],
[347, [revert_phantom, revert_hphantom, revert_vphantom]],
Item "Settings...|S" "inset-settings"
End
+#
+# Index context menu
+#
+
+ Menu "context-index"
+ IndicesContext
+ Separator
+ OptItem "Open Inset|O" "inset-toggle open"
+ OptItem "Close Inset|C" "inset-toggle close"
+ Separator
+ Item "Dissolve Inset|D" "inset-dissolve"
+ End
+
+#
+# Index Lists context menu
+#
+
+ Menu "context-indexprint"
+ IndicesListsContext
+ End
+
End
Item "Cross-Reference...|R" "dialog-show-new-inset ref"
Item "Label...|L" "label-insert"
Item "Caption" "caption-insert"
- Item "Index Entry|d" "index-insert"
+ Indices
Item "Nomenclature Entry...|y" "nomencl-insert"
Separator
Item "Table...|T" "tabular-insert"
Menu "insert_toc"
Item "Table of Contents|C" "toc-insert"
FloatListInsert
- Item "Index List|I" "index-print"
+ IndicesLists
Item "Nomenclature|N" "nomencl-print"
Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex"
End
#include "Format.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
+#include "IndicesList.h"
#include "InsetIterator.h"
#include "InsetList.h"
#include "Language.h"
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-int const LYX_FORMAT = 351; // uwestoehr: support for page background color
+int const LYX_FORMAT = 352; // jspitzm: splitindex support
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
params().clearLayoutModules();
params().clearRemovedModules();
params().pdfoptions().clear();
+ params().indiceslist().clear();
for (int i = 0; i < 4; ++i) {
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
#include "Color.h"
#include "ColorSet.h"
#include "Encoding.h"
+#include "IndicesList.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "ModuleList.h"
BranchList branchlist;
Bullet temp_bullets[4];
Bullet user_defined_bullets[4];
+ IndicesList indiceslist;
Spacing spacing;
/** This is the amount of space used for paragraph_separation "skip",
* and for detached paragraphs in "indented" documents.
use_esint = package_auto;
cite_engine_ = ENGINE_BASIC;
use_bibtopic = false;
+ use_indices = false;
trackChanges = false;
outputChanges = false;
use_default_options = true;
user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
}
+ // default index
+ indiceslist().addDefault(B_("Index"));
}
}
+IndicesList & BufferParams::indiceslist()
+{
+ return pimpl_->indiceslist;
+}
+
+
+IndicesList const & BufferParams::indiceslist() const
+{
+ return pimpl_->indiceslist;
+}
+
+
Bullet & BufferParams::temp_bullet(lyx::size_type const index)
{
LASSERT(index < 4, /**/);
cite_engine_ = citeenginetranslator().find(engine);
} else if (token == "\\use_bibtopic") {
lex >> use_bibtopic;
+ } else if (token == "\\use_indices") {
+ lex >> use_indices;
} else if (token == "\\tracking_changes") {
lex >> trackChanges;
} else if (token == "\\output_changes") {
lcolor.setColor(to_utf8(branch), color);
}
}
+ } else if (token == "\\index") {
+ lex.eatLine();
+ docstring index = lex.getDocString();
+ indiceslist().add(index);
+ while (true) {
+ lex.next();
+ string const tok = lex.getString();
+ if (tok == "\\end_index")
+ break;
+ Index * index_ptr = indiceslist().find(index);
+ if (tok == "\\shortcut") {
+ lex.next();
+ if (index_ptr)
+ index_ptr->setShortcut(lex.getDocString());
+ }
+ // not yet operational
+ if (tok == "\\color") {
+ lex.eatLine();
+ string color = lex.getString();
+ if (index_ptr)
+ index_ptr->setColor(color);
+ // Update also the Color table:
+ if (color == "none")
+ color = lcolor.getX11Name(Color_background);
+ // FIXME UNICODE
+ lcolor.setColor(to_utf8(index), color);
+ }
+ }
} else if (token == "\\author") {
lex.eatLine();
istringstream ss(lex.getString());
<< "\n\\use_esint " << use_esint
<< "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
<< "\n\\use_bibtopic " << convert<string>(use_bibtopic)
+ << "\n\\use_indices " << convert<string>(use_indices)
<< "\n\\paperorientation " << string_orientation[orientation]
<< "\n\\backgroundcolor " << lyx::X11hexname(backgroundcolor)
<< '\n';
<< "\n";
}
+ IndicesList::const_iterator iit = indiceslist().begin();
+ IndicesList::const_iterator iend = indiceslist().end();
+ for (; iit != iend; ++iit) {
+ os << "\\index " << to_utf8(iit->index())
+ << "\n\\shortcut " << to_utf8(iit->shortcut())
+ << "\n\\color " << lyx::X11hexname(iit->color())
+ << "\n\\end_index"
+ << "\n";
+ }
+
if (!paperwidth.empty())
os << "\\paperwidth "
<< VSpace(paperwidth).asLyXCommand() << '\n';
// The optional packages;
lyxpreamble += from_ascii(features.getPackages());
+ // Additional Indices
+ if (features.isRequired("splitidx")) {
+ IndicesList::const_iterator iit = indiceslist().begin();
+ IndicesList::const_iterator iend = indiceslist().end();
+ for (; iit != iend; ++iit) {
+ lyxpreamble += "\\newindex[";
+ lyxpreamble += iit->index();
+ lyxpreamble += "]{";
+ lyxpreamble += iit->shortcut();
+ lyxpreamble += "}\n";
+ }
+ }
+
// Line spacing
lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
class Bullet;
class DocumentClass;
class Encoding;
+class IndicesList;
class Language;
class LatexFeatures;
class LayoutFile;
/// BranchList:
BranchList & branchlist();
BranchList const & branchlist() const;
+ /// IndicesList:
+ IndicesList & indiceslist();
+ IndicesList const & indiceslist() const;
/**
* The input encoding for LaTeX. This can be one of
* - \c auto: find out the input encoding from the used languages
Package use_amsmath;
/// Whether and how to load esint
Package use_esint;
- ///
+ /// Split bibliography?
bool use_bibtopic;
+ /// Split the index?
+ bool use_indices;
/// revision tracking for this buffer ?
bool trackChanges;
/** This param decides whether change tracking marks should be used
// used anyway.
OutputParams runparams(buffer ? &buffer->params().encoding() : 0);
runparams.flavor = getFlavor(edgepath);
+
+ runparams.use_indices = buffer->params().use_indices;
if (buffer)
runparams.use_japanese = buffer->bufferFormat() == "platex";
--- /dev/null
+/**
+ * \file IndicesList.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "IndicesList.h"
+#include "Color.h"
+
+#include "frontends/Application.h"
+
+#include "support/convert.h"
+#include "support/lstrings.h"
+
+#include <algorithm>
+
+using namespace std;
+using namespace lyx::support;
+
+namespace lyx {
+
+namespace {
+
+class IndexNamesEqual : public std::unary_function<Index, bool>
+{
+public:
+ IndexNamesEqual(docstring const & name) : name_(name) {}
+
+ bool operator()(Index const & index) const
+ {
+ return index.index() == name_;
+ }
+private:
+ docstring name_;
+};
+
+
+class IndexHasShortcut : public std::unary_function<Index, bool>
+{
+public:
+ IndexHasShortcut(docstring const & shortcut) : shortc_(shortcut) {}
+
+ bool operator()(Index const & index) const
+ {
+ return index.shortcut() == shortc_;
+ }
+private:
+ docstring shortc_;
+};
+
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// Index
+//
+/////////////////////////////////////////////////////////////////////
+
+
+Index::Index()
+{
+ // no theApp() with command line export
+ if (theApp())
+ theApp()->getRgbColor(Color_indexlabel, color_);
+}
+
+
+docstring const & Index::index() const
+{
+ return index_;
+}
+
+
+void Index::setIndex(docstring const & s)
+{
+ index_ = s;
+}
+
+
+docstring const & Index::shortcut() const
+{
+ return shortcut_;
+}
+
+
+void Index::setShortcut(docstring const & s)
+{
+ shortcut_ = s;
+}
+
+
+RGBColor const & Index::color() const
+{
+ return color_;
+}
+
+
+void Index::setColor(RGBColor const & c)
+{
+ color_ = c;
+}
+
+
+void Index::setColor(string const & str)
+{
+ if (str.size() == 7 && str[0] == '#')
+ color_ = rgbFromHexName(str);
+ else
+ // no color set or invalid color -- use predefined color
+ theApp()->getRgbColor(Color_indexlabel, color_);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// IndicesList
+//
+/////////////////////////////////////////////////////////////////////
+
+
+Index * IndicesList::find(docstring const & name)
+{
+ List::iterator it =
+ find_if(list.begin(), list.end(), IndexNamesEqual(name));
+ return it == list.end() ? 0 : &*it;
+}
+
+
+Index const * IndicesList::find(docstring const & name) const
+{
+ List::const_iterator it =
+ find_if(list.begin(), list.end(), IndexNamesEqual(name));
+ return it == list.end() ? 0 : &*it;
+}
+
+
+Index * IndicesList::findShortcut(docstring const & shortcut)
+{
+ List::iterator it =
+ find_if(list.begin(), list.end(), IndexHasShortcut(shortcut));
+ return it == list.end() ? 0 : &*it;
+}
+
+
+Index const * IndicesList::findShortcut(docstring const & shortcut) const
+{
+ List::const_iterator it =
+ find_if(list.begin(), list.end(), IndexHasShortcut(shortcut));
+ return it == list.end() ? 0 : &*it;
+}
+
+
+bool IndicesList::add(docstring const & n, docstring const & s)
+{
+ bool added = false;
+ size_t i = 0;
+ while (true) {
+ size_t const j = n.find_first_of(separator_, i);
+ docstring name;
+ if (j == docstring::npos)
+ name = n.substr(i);
+ else
+ name = n.substr(i, j - i);
+ // Is this name already in the list?
+ bool const already =
+ find_if(list.begin(), list.end(),
+ IndexNamesEqual(name)) != list.end();
+ if (!already) {
+ added = true;
+ Index in;
+ in.setIndex(name);
+ docstring sc = s.empty() ?
+ trim(lowercase(name.substr(0, 3))) : s;
+ if (findShortcut(sc) != 0) {
+ int i = 1;
+ docstring scn = sc + convert<docstring>(i);
+ while (findShortcut(scn) != 0) {
+ ++i;
+ scn = sc + convert<docstring>(i);
+ }
+ in.setShortcut(scn);
+ } else
+ in.setShortcut(sc);
+ list.push_back(in);
+ }
+ if (j == docstring::npos)
+ break;
+ i = j + 1;
+ }
+ return added;
+}
+
+
+bool IndicesList::addDefault(docstring const & n)
+{
+ if (findShortcut(from_ascii("idx")) != 0)
+ // we already have a default
+ return false;
+ return add(n, from_ascii("idx"));
+}
+
+bool IndicesList::remove(docstring const & s)
+{
+ size_t const size = list.size();
+ list.remove_if(IndexNamesEqual(s));
+ return size != list.size();
+}
+
+
+bool IndicesList::rename(docstring const & oldname,
+ docstring const & newname)
+{
+ if (newname.empty())
+ return false;
+ if (find_if(list.begin(), list.end(),
+ IndexNamesEqual(newname)) != list.end())
+ // new name already taken
+ return false;
+
+ Index * index = find(oldname);
+ if (!index)
+ return false;
+ index->setIndex(newname);
+ return true;
+}
+
+
+} // namespace lyx
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file IndicesList.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ *
+ *
+ * \class Index
+ *
+ * A class describing an Index type, such as "Index of Names".
+ * Different Index types are used in splitted Indices
+ *
+ * An Index has a name and a shortcut notation. It uses a
+ * user-specifyable GUI colour. All these can be set and
+ * queried.
+ *
+ * \class IndicesList
+ *
+ * A class containing a vector of all defined indices within a
+ * document. Has methods for outputting a '|'-separated string
+ * of all elements, and for adding, removing and renaming elements.
+ */
+
+
+#ifndef INDICESLIST_H
+#define INDICESLIST_H
+
+#include "ColorCode.h"
+
+#include "support/docstring.h"
+
+#include <list>
+
+
+namespace lyx {
+
+class Index {
+public:
+ ///
+ Index();
+ ///
+ docstring const & index() const;
+ ///
+ void setIndex(docstring const &);
+ ///
+ docstring const & shortcut() const;
+ ///
+ void setShortcut(docstring const &);
+ ///
+ RGBColor const & color() const;
+ ///
+ void setColor(RGBColor const &);
+ /**
+ * Set color from a string "#rrggbb".
+ * Use Color:background if the string is no valid color.
+ * This ensures compatibility with LyX 1.4.0 that had the symbolic
+ * color "none" that was displayed as Color:background.
+ */
+ void setColor(std::string const &);
+
+private:
+ ///
+ docstring index_;
+ ///
+ docstring shortcut_;
+ ///
+ RGBColor color_;
+};
+
+
+class IndicesList {
+ ///
+ typedef std::list<Index> List;
+public:
+ typedef List::const_iterator const_iterator;
+
+ ///
+ IndicesList() : separator_(from_ascii("|")) {}
+
+ ///
+ bool empty() const { return list.empty(); }
+ ///
+ void clear() { list.clear(); }
+ ///
+ const_iterator begin() const { return list.begin(); }
+ const_iterator end() const { return list.end(); }
+
+ /** \returns the Index with \c name. If not found, returns 0.
+ */
+ Index * find(docstring const & name);
+ Index const * find(docstring const & name) const;
+
+ /** \returns the Index with the shortcut \c shortcut.
+ * If not found, returns 0.
+ */
+ Index * findShortcut(docstring const & shortcut);
+ Index const * findShortcut(docstring const & shortcut) const;
+
+ /** Add (possibly multiple (separated by separator())) indices to list
+ * \returns true if an index is added.
+ */
+ bool add(docstring const & n, docstring const & s = docstring());
+ /** Add the default index (if not already there)
+ * \returns true if an index is added.
+ */
+ bool addDefault(docstring const & n);
+ /** remove an index from list by name
+ * \returns true if an index is removed.
+ */
+ bool remove(docstring const &);
+ /** rename an index in list
+ * \returns true if renaming succeeded.
+ */
+ bool rename(docstring const &, docstring const &);
+
+private:
+ ///
+ List list;
+ ///
+ docstring separator_;
+};
+
+} // namespace lyx
+
+#endif // INDICESLIST_H
"idx file has been made, running makeindex on file " << f);
string tmp = runparams.use_japanese ?
lyxrc.jindex_command : lyxrc.index_command;
- tmp += ' ';
tmp = subst(tmp, "$$lang", runparams.document_language);
+ if (runparams.use_indices)
+ tmp = lyxrc.splitindex_command + " -m " + quoteName(tmp);
+ tmp += ' ';
tmp += quoteName(f);
tmp += params;
Systemcall one;
// [x]color and pdfcolmk are handled in getColorOptions() above
// makeidx.sty
- if (isRequired("makeidx")) {
- if (!tclass.provides("makeidx"))
+ if (isRequired("makeidx") || isRequired("splitidx")) {
+ if (!tclass.provides("makeidx") && !isRequired("splitidx"))
packages << "\\usepackage{makeidx}\n";
+ if (!tclass.provides("splitidx") && isRequired("splitidx"))
+ packages << "\\usepackage{splitidx}\n";
packages << "\\makeindex\n";
}
* \var lyx::FuncCode lyx::LFUN_INDEX_INSERT
* \li Action: Inserts Index entry.
* \li Notion: It automatically takes the word on the cursor position.
- * \li Syntax: index-insert
+ * \li Syntax: index-insert [<TYPE:Name>]
+ * \li Params: <TYPE:Name>: name of the index, if multiple indices are defined.
+ with an empty argument, the default index is selected.
* \li Origin: leeming, 3 Aug 2000
* \endvar
*/
/*!
* \var lyx::FuncCode lyx::LFUN_INDEX_PRINT
* \li Action: Inserts list of Index entries on a new page.
- * \li Syntax: index-print
+ * \li Syntax: index-print [<TYPE:Name>]
+ * \li Params: <TYPE:Name>: name of the index, if multiple indices are defined.
+ with an empty argument, the default index is selected.
* \li Origin: Lgb, 27 Feb 1997
* \endvar
*/
case LyXRC::RC_OPEN_BUFFERS_IN_TABS:
case LyXRC::RC_SPELL_COMMAND:
case LyXRC::RC_SPELLCHECK_CONTINUOUSLY:
+ case LyXRC::RC_SPLITINDEX_COMMAND:
case LyXRC::RC_TEMPDIRPATH:
case LyXRC::RC_TEMPLATEPATH:
case LyXRC::RC_TEX_ALLOWS_SPACES:
{ "\\sort_layouts", LyXRC::RC_SORT_LAYOUTS },
{ "\\spell_command", LyXRC::RC_SPELL_COMMAND },
{ "\\spellcheck_continuously", LyXRC::RC_SPELLCHECK_CONTINUOUSLY },
+ { "\\splitindex_command", LyXRC::RC_SPLITINDEX_COMMAND },
{ "\\tempdir_path", LyXRC::RC_TEMPDIRPATH },
{ "\\template_path", LyXRC::RC_TEMPLATEPATH },
{ "\\tex_allows_spaces", LyXRC::RC_TEX_ALLOWS_SPACES },
}
break;
+ case RC_SPLITINDEX_COMMAND:
+ if (lexrc.next(true)) {
+ splitindex_command = lexrc.getString();
+ }
+ break;
+
case RC_NOMENCL_COMMAND:
if (lexrc.next(true)) {
nomencl_command = lexrc.getString();
}
if (tag != RC_LAST)
break;
+ case RC_SPLITINDEX_COMMAND:
+ if (ignore_system_lyxrc ||
+ splitindex_command != system_lyxrc.splitindex_command) {
+ os << "\\splitindex_command \"" << escapeCommand(splitindex_command) << "\"\n";
+ }
+ if (tag != RC_LAST)
+ break;
case RC_NOMENCL_COMMAND:
if (ignore_system_lyxrc ||
nomencl_command != system_lyxrc.nomencl_command) {
RC_SORT_LAYOUTS,
RC_SPELL_COMMAND,
RC_SPELLCHECK_CONTINUOUSLY,
+ RC_SPLITINDEX_COMMAND,
RC_TEMPDIRPATH,
RC_TEMPLATEPATH,
RC_TEX_ALLOWS_SPACES,
std::string index_command;
/// command to run japanese index program incl. options
std::string jindex_command;
+ /// command to generate multiple indices
+ std::string splitindex_command;
/// command to run makeindex incl. options for nomencl
std::string nomencl_command;
///
FuncRequest.cpp \
FuncStatus.cpp \
Graph.cpp \
+ IndicesList.cpp \
InsetIterator.cpp \
InsetList.cpp \
Intl.cpp \
FuncRequest.h \
FuncStatus.h \
Graph.h \
+ IndicesList.h \
InsetIterator.h \
InsetList.h \
Intl.h \
OutputParams::OutputParams(Encoding const * enc)
: flavor(LATEX), nice(false), moving_arg(false),
local_font(0), encoding(enc), free_spacing(false), use_babel(false),
- use_japanese(false), linelen(0), depth(0),
+ use_indices(false), use_japanese(false), linelen(0), depth(0),
exportdata(new ExportData),
inComment(false), inTableCell(NO), inFloat(NONFLOAT),
inDeletedInset(0), changeOfDeletedInset(Change::UNCHANGED),
*/
bool use_babel;
+ /** Are we generating multiple indices?
+ */
+ bool use_indices;
+
/** Are we using japanese (pLaTeX)?
*/
bool use_japanese;
break;
}
- case LFUN_INDEX_PRINT:
+ case LFUN_INDEX_PRINT: {
+ InsetCommandParams p(INDEX_PRINT_CODE);
+ if (cmd.argument().empty())
+ p["type"] = from_ascii("idx");
+ else
+ p["type"] = cmd.argument();
+ string const data = InsetCommand::params2string("index_print", p);
+ FuncRequest fr(LFUN_INSET_INSERT, data);
+ dispatch(cur, fr);
+ break;
+ }
+
case LFUN_NOMENCL_PRINT:
case LFUN_TOC_INSERT:
case LFUN_LINE_INSERT:
return 0;
}
- case LFUN_INDEX_INSERT:
- return new InsetIndex(buf);
+ case LFUN_INDEX_INSERT: {
+ docstring arg = cmd.argument();
+ return new InsetIndex(buf, InsetIndexParams(arg));
+ }
case LFUN_NOMENCL_INSERT: {
InsetCommandParams icp(NOMENCL_CODE);
case LFUN_CAPTION_INSERT:
return new InsetCaption(buf);
- case LFUN_INDEX_PRINT:
- return new InsetPrintIndex(InsetCommandParams(INDEX_PRINT_CODE));
+ case LFUN_INDEX_PRINT: {
+ InsetCommandParams icp(INDEX_PRINT_CODE);
+ icp["type"] = cmd.argument();
+ return new InsetPrintIndex(icp);
+ }
case LFUN_NOMENCL_PRINT:
return new InsetPrintNomencl(InsetCommandParams(NOMENCL_PRINT_CODE));
return new InsetInclude(icp);
}
- case INDEX_CODE:
- return new InsetIndex(buf);
+ case INDEX_CODE: {
+ docstring arg = cmd.argument();
+ return new InsetIndex(buf, InsetIndexParams(arg));
+ }
+
+ case INDEX_PRINT_CODE: {
+ InsetCommandParams icp(code);
+ InsetCommand::string2params(name, to_utf8(cmd.argument()), icp);
+ return new InsetPrintIndex(icp);
+ }
case NOMENCL_CODE: {
InsetCommandParams icp(code);
} else if (tmptok == "Caption") {
inset.reset(new InsetCaption(buf));
} else if (tmptok == "Index") {
- inset.reset(new InsetIndex(buf));
+ inset.reset(new InsetIndex(buf, InsetIndexParams()));
} else if (tmptok == "FloatList") {
inset.reset(new InsetFloatList);
} else if (tmptok == "Info") {
#include "GuiApplication.h"
#include "GuiBranches.h"
+#include "GuiIndices.h"
#include "GuiSelectionManager.h"
#include "LaTeXHighlighter.h"
#include "LengthCombo.h"
#include "FloatPlacement.h"
#include "Format.h"
#include "FuncRequest.h"
+#include "IndicesList.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "Layout.h"
biblioModule->citeStyleCO->addItem(qt_("Numerical"));
biblioModule->citeStyleCO->setCurrentIndex(0);
+ // indices
+ indicesModule = new GuiIndices;
+ connect(indicesModule, SIGNAL(changed()),
+ this, SLOT(change_adaptor()));
+
mathsModule = new UiWidget<Ui::MathsUi>;
connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
docPS->addPanel(langModule, qt_("Language"));
docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
docPS->addPanel(biblioModule, qt_("Bibliography"));
+ docPS->addPanel(indicesModule, qt_("Indices"));
docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
docPS->addPanel(mathsModule, qt_("Math Options"));
docPS->addPanel(floatModule, qt_("Float Placement"));
bp_.use_bibtopic =
biblioModule->bibtopicCB->isChecked();
+ // Indices
+ indicesModule->apply(bp_);
+
// language & quotes
if (langModule->defaultencodingRB->isChecked()) {
bp_.inputenc = "auto";
biblioModule->bibtopicCB->setChecked(
bp_.use_bibtopic);
+ // indices
+ indicesModule->update(bp_);
+
// language & quotes
int const pos = langModule->languageCO->findData(toqstr(
bp_.language->lang()));
dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
"assign branch"));
}
+ // Generate the colours requested by indices.
+ IndicesList & indiceslist = params().indiceslist();
+ if (!indiceslist.empty()) {
+ IndicesList::const_iterator it = indiceslist.begin();
+ IndicesList::const_iterator const end = indiceslist.end();
+ for (; it != end; ++it) {
+ docstring const & current_index = it->index();
+ Index const * index = indiceslist.find(current_index);
+ string const x11hexname = X11hexname(index->color());
+ // display the new color
+ docstring const str = current_index + ' ' + from_ascii(x11hexname);
+ dispatch(FuncRequest(LFUN_SET_COLOR, str));
+ }
+ }
// FIXME: If we used an LFUN, we would not need those two lines:
BufferView * bv = const_cast<BufferView *>(bufferview());
bv->processUpdateFlags(Update::Force | Update::FitCursor);
namespace frontend {
class GuiBranches;
+class GuiIndices;
class ModuleSelectionManager;
class PreambleModule;
UiWidget<Ui::PDFSupportUi> *pdfSupportModule;
UiWidget<Ui::ModulesUi> *modulesModule;
UiWidget<Ui::OutputUi> *outputModule;
- PreambleModule *preambleModule;
+ PreambleModule * preambleModule;
- GuiBranches *branchesModule;
+ GuiBranches * branchesModule;
+ GuiIndices * indicesModule;
BulletsModule * bulletsModule;
FloatPlacement * floatModule;
--- /dev/null
+/**
+ * \file GuiIndices.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Edwin Leuven
+ * \author Jürgen Spitzmüller
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "GuiIndices.h"
+
+#include "ColorCache.h"
+#include "GuiApplication.h"
+#include "Validator.h"
+#include "qt_helpers.h"
+
+#include "frontends/alert.h"
+
+#include "BufferParams.h"
+
+#include "support/gettext.h"
+#include "support/lstrings.h"
+
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QPixmap>
+#include <QIcon>
+#include <QColor>
+#include <QColorDialog>
+
+
+namespace lyx {
+namespace frontend {
+
+
+GuiIndices::GuiIndices(QWidget * parent)
+ : QWidget(parent)
+{
+ setupUi(this);
+ indicesTW->setColumnCount(2);
+ indicesTW->headerItem()->setText(0, qt_("Name"));
+ indicesTW->headerItem()->setText(1, qt_("Label Color"));
+ indicesTW->setSortingEnabled(true);
+}
+
+void GuiIndices::update(BufferParams const & params)
+{
+ indiceslist_ = params.indiceslist();
+ multipleIndicesCB->setChecked(
+ params.use_indices);
+ bool const state = params.use_indices;
+ indicesTW->setEnabled(state);
+ newIndexLE->setEnabled(state);
+ newIndexLA->setEnabled(state);
+ addIndexPB->setEnabled(state);
+ availableLA->setEnabled(state);
+ removePB->setEnabled(state);
+ colorPB->setEnabled(state);
+ updateView();
+}
+
+
+void GuiIndices::updateView()
+{
+ // store the selected index
+ QTreeWidgetItem * item = indicesTW->currentItem();
+ QString sel_index;
+ if (item != 0)
+ sel_index = item->text(0);
+
+ indicesTW->clear();
+
+ IndicesList::const_iterator it = indiceslist_.begin();
+ IndicesList::const_iterator const end = indiceslist_.end();
+ for (; it != end; ++it) {
+ QTreeWidgetItem * newItem = new QTreeWidgetItem(indicesTW);
+
+ QString const iname = toqstr(it->index());
+ newItem->setText(0, iname);
+
+ QColor const itemcolor = rgb2qcolor(it->color());
+ if (itemcolor.isValid()) {
+ QPixmap coloritem(30, 10);
+ coloritem.fill(itemcolor);
+ newItem->setIcon(1, QIcon(coloritem));
+ }
+ // restore selected index
+ if (iname == sel_index) {
+ indicesTW->setCurrentItem(newItem);
+ indicesTW->setItemSelected(newItem, true);
+ }
+ }
+ // emit signal
+ changed();
+}
+
+
+void GuiIndices::apply(BufferParams & params) const
+{
+ params.use_indices = multipleIndicesCB->isChecked();
+ params.indiceslist() = indiceslist_;
+}
+
+
+void GuiIndices::on_addIndexPB_pressed()
+{
+ QString const new_index = newIndexLE->text();
+ if (!new_index.isEmpty()) {
+ indiceslist_.add(qstring_to_ucs4(new_index));
+ newIndexLE->clear();
+ updateView();
+ }
+}
+
+
+void GuiIndices::on_removePB_pressed()
+{
+ QTreeWidgetItem * selItem = indicesTW->currentItem();
+ QString sel_index;
+ if (selItem != 0)
+ sel_index = selItem->text(0);
+ if (!sel_index.isEmpty()) {
+ if (indiceslist_.find(qstring_to_ucs4(sel_index)) ==
+ indiceslist_.findShortcut(from_ascii("idx"))) {
+ Alert::error(_("Cannot remove standard index"),
+ _("The default index cannot be removed."));
+ return;
+ }
+ indiceslist_.remove(qstring_to_ucs4(sel_index));
+ newIndexLE->clear();
+ updateView();
+ }
+}
+
+
+void GuiIndices::on_renamePB_clicked()
+{
+ QTreeWidgetItem * selItem = indicesTW->currentItem();
+ QString sel_index;
+ if (selItem != 0)
+ sel_index = selItem->text(0);
+ if (!sel_index.isEmpty()) {
+ docstring newname;
+ bool success = false;
+ if (Alert::askForText(newname, _("Enter new index name"))) {
+ success = indiceslist_.rename(qstring_to_ucs4(sel_index), newname);
+ newIndexLE->clear();
+ updateView();
+ }
+ if (!success)
+ Alert::error(_("Renaming failed"),
+ _("The index could not be renamed. "
+ "Check if the new name already exists."));
+ }
+}
+
+
+void GuiIndices::on_indicesTW_itemDoubleClicked(QTreeWidgetItem * item, int /*col*/)
+{
+ toggleColor(item);
+}
+
+
+void GuiIndices::on_colorPB_clicked()
+{
+ toggleColor(indicesTW->currentItem());
+}
+
+
+void GuiIndices::on_multipleIndicesCB_toggled(bool const state)
+{
+ indicesTW->setEnabled(state);
+ newIndexLE->setEnabled(state);
+ newIndexLA->setEnabled(state);
+ addIndexPB->setEnabled(state);
+ availableLA->setEnabled(state);
+ removePB->setEnabled(state);
+ colorPB->setEnabled(state);
+ // emit signal
+ changed();
+}
+
+
+void GuiIndices::toggleColor(QTreeWidgetItem * item)
+{
+ if (item == 0)
+ return;
+
+ QString sel_index = item->text(0);
+ if (sel_index.isEmpty())
+ return;
+
+ docstring current_index = qstring_to_ucs4(sel_index);
+ Index * index = indiceslist_.find(current_index);
+ if (!index)
+ return;
+
+ QColor const initial = rgb2qcolor(index->color());
+ QColor ncol = QColorDialog::getColor(initial, qApp->focusWidget());
+ if (!ncol.isValid())
+ return;
+
+ // add the color to the indiceslist
+ index->setColor(fromqstr(ncol.name()));
+ newIndexLE->clear();
+ updateView();
+}
+
+} // namespace frontend
+} // namespace lyx
+
+#include "moc_GuiIndices.cpp"
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file GuiIndices.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Edwin Leuven
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef GUIINDICES_H
+#define GUIINDICES_H
+
+#include "GuiDocument.h"
+#include "ui_IndicesUi.h"
+#include "IndicesList.h"
+
+#include <QWidget>
+
+class QTreeWidgetItem;
+
+namespace lyx {
+
+class BufferParams;
+
+namespace frontend {
+
+class GuiIndices : public QWidget, public Ui::IndicesUi
+{
+ Q_OBJECT
+public:
+ GuiIndices(QWidget * parent = 0);
+
+ void update(BufferParams const & params);
+ void apply(BufferParams & params) const;
+
+Q_SIGNALS:
+ void changed();
+
+protected:
+ void toggleColor(QTreeWidgetItem *);
+ void updateView();
+
+protected Q_SLOTS:
+ void on_addIndexPB_pressed();
+ void on_renamePB_clicked();
+ void on_removePB_pressed();
+ void on_indicesTW_itemDoubleClicked(QTreeWidgetItem *, int);
+ void on_colorPB_clicked();
+ void on_multipleIndicesCB_toggled(bool);
+
+private:
+ /// Contains all legal indices for this doc
+ IndicesList indiceslist_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // GUIINDICES_H
GuiIdListModel.cpp \
GuiImage.cpp \
GuiInclude.cpp \
+ GuiIndices.cpp \
GuiInfo.cpp \
GuiKeySymbol.cpp \
GuiLabel.cpp \
GuiHSpace.h \
GuiHyperlink.h \
GuiInclude.h \
+ GuiIndices.h \
GuiInfo.h \
GuiLabel.h \
GuiListings.h \
HSpaceUi.ui \
HyperlinkUi.ui \
IncludeUi.ui \
+ IndicesUi.ui \
InfoUi.ui \
LabelUi.ui \
LanguageUi.ui \
#include "Format.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
+#include "IndicesList.h"
#include "KeyMap.h"
#include "Lexer.h"
#include "LyXAction.h"
Toolbars,
/** Available branches in document */
Branches,
+ /** Available indices in document */
+ Indices,
+ /** Context menu for indices in document */
+ IndicesContext,
+ /** Available index lists in document */
+ IndicesLists,
+ /** Context menu for available indices lists in document */
+ IndicesListsContext,
/** Available citation styles for a given citation */
CiteStyles,
/** Available graphics groups */
void expandPasteRecent(Buffer const * buf);
void expandToolbars();
void expandBranches(Buffer const * buf);
+ void expandIndices(Buffer const * buf, bool listof = false);
+ void expandIndicesContext(Buffer const * buf, bool listof = false);
void expandCiteStyles(BufferView const *);
void expandGraphicsGroups(BufferView const *);
///
md_endmenu,
md_exportformats,
md_importformats,
+ md_indices,
+ md_indicescontext,
+ md_indiceslists,
+ md_indiceslistscontext,
md_lastfiles,
md_optitem,
md_optsubmenu,
{ "floatlistinsert", md_floatlistinsert },
{ "graphicsgroups", md_graphicsgroups },
{ "importformats", md_importformats },
+ { "indices", md_indices },
+ { "indicescontext", md_indicescontext },
+ { "indiceslists", md_indiceslists },
+ { "indiceslistscontext", md_indiceslistscontext },
{ "item", md_item },
{ "lastfiles", md_lastfiles },
{ "optitem", md_optitem },
add(MenuItem(MenuItem::GraphicsGroups));
break;
+ case md_indices:
+ add(MenuItem(MenuItem::Indices));
+ break;
+
+ case md_indicescontext:
+ add(MenuItem(MenuItem::IndicesContext));
+ break;
+
+ case md_indiceslists:
+ add(MenuItem(MenuItem::IndicesLists));
+ break;
+
+ case md_indiceslistscontext:
+ add(MenuItem(MenuItem::IndicesListsContext));
+ break;
+
case md_optsubmenu:
optional = true;
// fallback to md_submenu
}
+void MenuDefinition::expandIndices(Buffer const * buf, bool listof)
+{
+ if (!buf)
+ return;
+
+ BufferParams const & params = buf->masterBuffer()->params();
+ if (!params.use_indices) {
+ if (listof)
+ addWithStatusCheck(MenuItem(MenuItem::Command,
+ qt_("Index List|I"),
+ FuncRequest(LFUN_INDEX_PRINT,
+ from_ascii("idx"))));
+ else
+ addWithStatusCheck(MenuItem(MenuItem::Command,
+ qt_("Index Entry|d"),
+ FuncRequest(LFUN_INDEX_INSERT,
+ from_ascii("idx"))));
+ return;
+ }
+
+ if (params.indiceslist().empty())
+ return;
+
+ IndicesList::const_iterator cit = params.indiceslist().begin();
+ IndicesList::const_iterator end = params.indiceslist().end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ if (listof)
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+ FuncRequest(LFUN_INDEX_PRINT,
+ cit->shortcut())));
+ else {
+ docstring label = _("Index Entry");
+ label += " (" + cit->index() + ")";
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_INDEX_INSERT,
+ cit->shortcut())));
+ }
+ }
+}
+
+
+void MenuDefinition::expandIndicesContext(Buffer const * buf, bool listof)
+{
+ if (!buf)
+ return;
+
+ BufferParams const & params = buf->masterBuffer()->params();
+ if (!params.use_indices || params.indiceslist().empty())
+ return;
+
+ IndicesList::const_iterator cit = params.indiceslist().begin();
+ IndicesList::const_iterator end = params.indiceslist().end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ if (listof) {
+ InsetCommandParams p(INDEX_PRINT_CODE);
+ p["type"] = cit->shortcut();
+ string const data = InsetCommand::params2string("index_print", p);
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+ FuncRequest(LFUN_NEXT_INSET_MODIFY, data)));
+ } else {
+ docstring label = _("Index Entry");
+ label += " (" + cit->index() + ")";
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_NEXT_INSET_MODIFY,
+ from_ascii("changetype ") + cit->shortcut())));
+ }
+ }
+}
+
+
void MenuDefinition::expandCiteStyles(BufferView const * bv)
{
if (!bv)
/// Expands some special entries of the menu
/** The entries with the following kind are expanded to a
sequence of Command MenuItems: Lastfiles, Documents,
- ViewFormats, ExportFormats, UpdateFormats, Branches
+ ViewFormats, ExportFormats, UpdateFormats, Branches, Indices
*/
void expand(MenuDefinition const & frommenu, MenuDefinition & tomenu,
BufferView const *) const;
tomenu.expandBranches(buf);
break;
+ case MenuItem::Indices:
+ tomenu.expandIndices(buf);
+ break;
+
+ case MenuItem::IndicesContext:
+ tomenu.expandIndicesContext(buf);
+ break;
+
+ case MenuItem::IndicesLists:
+ tomenu.expandIndices(buf, true);
+ break;
+
+ case MenuItem::IndicesListsContext:
+ tomenu.expandIndicesContext(buf, true);
+ break;
+
case MenuItem::CiteStyles:
tomenu.expandCiteStyles(bv);
break;
--- /dev/null
+<ui version="4.0" >
+ <class>IndicesUi</class>
+ <widget class="QWidget" name="IndicesUi" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>401</width>
+ <height>340</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="2" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="newIndexLA" >
+ <property name="text" >
+ <string>&New:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>newIndexLE</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="newIndexLE" >
+ <property name="toolTip" >
+ <string>Enter the name of the desired index (e.g. "Index of Names") and hit "Add"</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addIndexPB" >
+ <property name="toolTip" >
+ <string>Add a new branch to the list</string>
+ </property>
+ <property name="text" >
+ <string>&Add</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="removePB" >
+ <property name="toolTip" >
+ <string>Remove the selected index</string>
+ </property>
+ <property name="text" >
+ <string>&Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>121</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="availableLA" >
+ <property name="text" >
+ <string>A&vailable Indices:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>indicesTW</cstring>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="4" row="4" column="0" >
+ <widget class="QTreeWidget" name="indicesTW" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="multipleIndicesCB" >
+ <property name="toolTip" >
+ <string>Check if you need multiple indices (e.g., an Index of Names)</string>
+ </property>
+ <property name="text" >
+ <string>&Use multiple indices</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" >
+ <widget class="QPushButton" name="colorPB" >
+ <property name="toolTip" >
+ <string>Define or change button color</string>
+ </property>
+ <property name="text" >
+ <string>Alter Co&lor...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" >
+ <widget class="QPushButton" name="renamePB" >
+ <property name="toolTip" >
+ <string>Rename the selected index</string>
+ </property>
+ <property name="text" >
+ <string>R&ename...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <includes>
+ <include location="local" >qt_i18n.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
+ * \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
#include "InsetIndex.h"
#include "Buffer.h"
+#include "BufferParams.h"
+#include "ColorSet.h"
#include "DispatchResult.h"
#include "Encoding.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
+#include "IndicesList.h"
#include "LaTeXFeatures.h"
+#include "Lexer.h"
#include "MetricsInfo.h"
#include "sgml.h"
#include "TocBackend.h"
///////////////////////////////////////////////////////////////////////
-InsetIndex::InsetIndex(Buffer const & buf)
- : InsetCollapsable(buf)
+InsetIndex::InsetIndex(Buffer const & buf, InsetIndexParams const & params)
+ : InsetCollapsable(buf), params_(params)
{}
int InsetIndex::latex(odocstream & os,
OutputParams const & runparams) const
{
- os << "\\index";
- os << '{';
+ if (buffer().masterBuffer()->params().use_indices && !params_.index.empty()
+ && params_.index != "idx") {
+ os << "\\sindex[";
+ os << params_.index;
+ os << "]{";
+ } else {
+ os << "\\index";
+ os << '{';
+ }
int i = 0;
// get contents of InsetText as LaTeX and plaintext
}
+void InsetIndex::doDispatch(Cursor & cur, FuncRequest & cmd)
+{
+ switch (cmd.action) {
+
+ case LFUN_INSET_MODIFY: {
+ if (cmd.getArg(0) == "changetype") {
+ params_.index = from_utf8(cmd.getArg(1));
+ setLayout(cur.buffer()->params());
+ break;
+ }
+ }
+
+ default:
+ InsetCollapsable::doDispatch(cur, cmd);
+ break;
+ }
+}
+
+
+bool InsetIndex::getStatus(Cursor & cur, FuncRequest const & cmd,
+ FuncStatus & flag) const
+{
+ switch (cmd.action) {
+
+ case LFUN_INSET_MODIFY:
+ if (cmd.getArg(0) == "changetype") {
+ docstring const newtype = from_utf8(cmd.getArg(1));
+ Buffer const & realbuffer = *buffer().masterBuffer();
+ IndicesList const & indiceslist = realbuffer.params().indiceslist();
+ Index const * index = indiceslist.findShortcut(newtype);
+ flag.setEnabled(index != 0);
+ flag.setOnOff(
+ from_utf8(cmd.getArg(1)) == params_.index);
+ return true;
+ }
+
+ default:
+ return InsetCollapsable::getStatus(cur, cmd, flag);
+ }
+}
+
+
+docstring const InsetIndex::buttonLabel(BufferView const & bv) const
+{
+ docstring s = _("Idx");
+ if (decoration() == InsetLayout::CLASSIC)
+ return isOpen(bv) ? s : getNewLabel(s);
+ else
+ return getNewLabel(s);
+}
+
+
+docstring InsetIndex::toolTip(BufferView const &, int, int) const
+{
+ docstring tip = _("Index Entry");
+ if (buffer().params().use_indices && !params_.index.empty()) {
+ Buffer const & realbuffer = *buffer().masterBuffer();
+ IndicesList const & indiceslist = realbuffer.params().indiceslist();
+ tip += " (";
+ Index const * index = indiceslist.findShortcut(params_.index);
+ if (!index)
+ tip += _("unknown type!");
+ else
+ tip += index->index();
+ tip += ")";
+ }
+ tip += ": ";
+ OutputParams rp(&buffer().params().encoding());
+ odocstringstream ods;
+ InsetText::plaintext(ods, rp);
+ tip += ods.str();
+ // shorten it if necessary
+ if (tip.size() > 200)
+ tip = tip.substr(0, 200) + "...";
+ return tip;
+}
+
+
void InsetIndex::write(ostream & os) const
{
- os << to_utf8(name()) << "\n";
+ os << to_utf8(name());
+ params_.write(os);
InsetCollapsable::write(os);
}
+void InsetIndex::read(Lexer & lex)
+{
+ params_.read(lex);
+ InsetCollapsable::read(lex);
+}
+
+
void InsetIndex::addToToc(DocIterator const & cpit)
{
DocIterator pit = cpit;
}
+void InsetIndex::validate(LaTeXFeatures & features) const
+{
+ if (buffer().masterBuffer()->params().use_indices
+ && !params_.index.empty()
+ && params_.index != "idx")
+ features.require("splitidx");
+}
+
+
+docstring InsetIndex::contextMenu(BufferView const &, int, int) const
+{
+ return from_ascii("context-index");
+}
+
+
+void InsetIndexParams::write(ostream & os) const
+{
+ os << ' ';
+ if (!index.empty())
+ os << to_utf8(index);
+ else
+ os << "idx";
+ os << '\n';
+}
+
+
+void InsetIndexParams::read(Lexer & lex)
+{
+ if (lex.eatLine())
+ index = lex.getDocString();
+ else
+ index = from_ascii("idx");
+}
+
+
/////////////////////////////////////////////////////////////////////
//
// InsetPrintIndex
///////////////////////////////////////////////////////////////////////
InsetPrintIndex::InsetPrintIndex(InsetCommandParams const & p)
- : InsetCommand(p, string())
+ : InsetCommand(p, "index_print")
{}
ParamInfo const & InsetPrintIndex::findInfo(string const & /* cmdName */)
{
static ParamInfo param_info_;
- if (param_info_.empty())
+ if (param_info_.empty()) {
+ param_info_.add("type", ParamInfo::LATEX_OPTIONAL);
param_info_.add("name", ParamInfo::LATEX_REQUIRED);
+ }
return param_info_;
}
docstring InsetPrintIndex::screenLabel() const
{
- return _("Index");
+ if ((!buffer().masterBuffer()->params().use_indices
+ && getParam("type") == from_ascii("idx"))
+ || getParam("type").empty())
+ return _("Index");
+ Buffer const & realbuffer = *buffer().masterBuffer();
+ IndicesList const & indiceslist = realbuffer.params().indiceslist();
+ Index const * index = indiceslist.findShortcut(getParam("type"));
+ if (!index)
+ return _("Unknown index type!");
+ docstring res = index->index();
+ if (!buffer().masterBuffer()->params().use_indices)
+ res += " (" + _("non-active") + ")";
+ return res;
+}
+
+
+bool InsetPrintIndex::getStatus(Cursor & cur, FuncRequest const & cmd,
+ FuncStatus & status) const
+{
+ switch (cmd.action) {
+
+ case LFUN_INSET_MODIFY: {
+ InsetCommandParams p(INDEX_PRINT_CODE);
+ InsetCommand::string2params("index_print", to_utf8(cmd.argument()), p);
+ Buffer const & realbuffer = *buffer().masterBuffer();
+ IndicesList const & indiceslist = realbuffer.params().indiceslist();
+ Index const * index = indiceslist.findShortcut(p["type"]);
+ status.setEnabled(index != 0);
+ status.setOnOff(p["type"] == getParam("type"));
+ return true;
+ }
+
+ default:
+ return InsetCommand::getStatus(cur, cmd, status);
+ }
+}
+
+
+int InsetPrintIndex::latex(odocstream & os, OutputParams const &) const
+{
+ if (!buffer().masterBuffer()->params().use_indices) {
+ if (getParam("type") == from_ascii("idx"))
+ os << "\\printindex{}";
+ return 0;
+ }
+ os << getCommand();
+ return 0;
}
void InsetPrintIndex::validate(LaTeXFeatures & features) const
{
features.require("makeidx");
+ if (buffer().masterBuffer()->params().use_indices)
+ features.require("splitidx");
}
-InsetCode InsetPrintIndex::lyxCode() const
+docstring InsetPrintIndex::contextMenu(BufferView const &, int, int) const
{
- return INDEX_PRINT_CODE;
+ return buffer().masterBuffer()->params().use_indices ?
+ from_ascii("context-indexprint") : docstring();
}
} // namespace lyx
namespace lyx {
+class InsetIndexParams {
+public:
+ ///
+ explicit InsetIndexParams(docstring const & b = docstring())
+ : index(b) {}
+ ///
+ void write(std::ostream & os) const;
+ ///
+ void read(Lexer & lex);
+ ///
+ docstring index;
+};
+
+
/** Used to insert index labels
*/
class InsetIndex : public InsetCollapsable {
public:
///
- InsetIndex(Buffer const &);
+ InsetIndex(Buffer const &, InsetIndexParams const &);
private:
///
EDITABLE editable() const { return HIGHLY_EDITABLE; }
///
void write(std::ostream & os) const;
///
+ void read(Lexer & lex);
+ ///
int docbook(odocstream &, OutputParams const &) const;
///
int latex(odocstream &, OutputParams const &) const;
+ ///
+ bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+ ///
+ void doDispatch(Cursor & cur, FuncRequest & cmd);
/// should paragraph indendation be omitted in any case?
bool neverIndent() const { return true; }
///
void addToToc(DocIterator const &);
///
+ docstring const buttonLabel(BufferView const & bv) const;
+ ///
+ docstring toolTip(BufferView const & bv, int x, int y) const;
+ /// Updates needed features for this inset.
+ void validate(LaTeXFeatures & features) const;
+ ///
+ docstring contextMenu(BufferView const & bv, int x, int y) const;
+ ///
Inset * clone() const { return new InsetIndex(*this); }
+
+ ///
+ friend class InsetIndexParams;
+ ///
+ InsetIndexParams params_;
};
public:
///
InsetPrintIndex(InsetCommandParams const &);
+ ///
+ InsetCode lyxCode() const { return INDEX_PRINT_CODE; }
///
static ParamInfo const & findInfo(std::string const &);
///
static bool isCompatibleCommand(std::string const & s)
{ return s == "printindex"; }
+ ///
+ int latex(odocstream &, OutputParams const &) const;
+ ///
+ bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+ ///
+ virtual docstring contextMenu(BufferView const & bv, int x, int y) const;
private:
/// Updates needed features for this inset.
void validate(LaTeXFeatures & features) const;
///
EDITABLE editable() const { return NOT_EDITABLE; }
///
- InsetCode lyxCode() const;
- ///
DisplayType display() const { return AlignCenter; }
///
docstring screenLabel() const;