]> git.lyx.org Git - lyx.git/blobdiff - src/TextClass.cpp
Account for old versions of Pygments
[lyx.git] / src / TextClass.cpp
index 5b71cb0496c9a3a38c629147f3225a86a79fc37c..612539843f0b2148574d4eb3cb512ce113786e6e 100644 (file)
@@ -17,6 +17,7 @@
 #include "TextClass.h"
 
 #include "LayoutFile.h"
+#include "CiteEnginesList.h"
 #include "Color.h"
 #include "Counters.h"
 #include "Floating.h"
@@ -61,7 +62,7 @@ namespace lyx {
 // You should also run the development/tools/updatelayouts.py script,
 // to update the format of all of our layout files.
 //
-int const LAYOUT_FORMAT = 61; //spitz ResumeCounter, StepMasterCounter
+int const LAYOUT_FORMAT = 63; //spitz: new tags CiteFramework, MaxCiteNames, extended InsetCite syntax.
 
 
 // Layout format for the current lyx file format. Controls which format is
@@ -123,6 +124,8 @@ string translateReadType(TextClass::ReadType rt)
                return "input file";
        case TextClass::MODULE:
                return "module file";
+       case TextClass::CITE_ENGINE:
+               return "cite engine";
        case TextClass::VALIDATION:
                return "validation";
        }
@@ -152,7 +155,7 @@ TextClass::TextClass()
          outputType_(LATEX), outputFormat_("latex"),
          defaultfont_(sane_font),
          titletype_(TITLE_COMMAND_AFTER), titlename_("maketitle"),
-         min_toclevel_(0), max_toclevel_(0),
+         min_toclevel_(0), max_toclevel_(0), maxcitenames_(2),
          cite_full_author_list_(true)
 {
 }
@@ -218,6 +221,8 @@ enum TextClassTags {
        TC_CITEENGINE,
        TC_CITEENGINETYPE,
        TC_CITEFORMAT,
+       TC_CITEFRAMEWORK,
+       TC_MAXCITENAMES,
        TC_DEFAULTBIBLIO,
        TC_FULLAUTHORLIST,
        TC_OUTLINERNAME
@@ -233,6 +238,7 @@ LexerKeyword textClassTags[] = {
        { "citeengine",        TC_CITEENGINE },
        { "citeenginetype",    TC_CITEENGINETYPE },
        { "citeformat",        TC_CITEFORMAT },
+       { "citeframework",     TC_CITEFRAMEWORK },
        { "classoptions",      TC_CLASSOPTIONS },
        { "columns",           TC_COLUMNS },
        { "counter",           TC_COUNTER },
@@ -251,6 +257,7 @@ LexerKeyword textClassTags[] = {
        { "input",             TC_INPUT },
        { "insetlayout",       TC_INSETLAYOUT },
        { "leftmargin",        TC_LEFTMARGIN },
+       { "maxcitenames",      TC_MAXCITENAMES },
        { "modifystyle",       TC_MODIFYSTYLE },
        { "nocounter",         TC_NOCOUNTER },
        { "nofloat",           TC_NOFLOAT },
@@ -456,8 +463,13 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
 
                case TC_INPUT: // Include file
                        if (lexrc.next()) {
+                               FileName tmp;
                                string const inc = lexrc.getString();
-                               FileName tmp = libFileSearch("layouts", inc,
+                               if (!path().empty() && (prefixIs(inc, "./") ||
+                                                       prefixIs(inc, "../")))
+                                       tmp = fileSearch(path(), inc, "layout");
+                               else
+                                       tmp = libFileSearch("layouts", inc,
                                                            "layout");
 
                                if (tmp.empty()) {
@@ -537,9 +549,8 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        // Either way, we just scan the rest and discard it
                        else {
                                Layout lay;
-                               // false positive from coverity
-                               // coverity[CHECKED_RETURN]
-                               readStyle(lexrc, lay);
+                               // signal to coverity that we do not care about the result
+                               (void)readStyle(lexrc, lay);
                        }
                        break;
                }
@@ -614,15 +625,15 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        break;
 
                case TC_PREAMBLE:
-                       preamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
+                       preamble_ = lexrc.getLongString(from_ascii("EndPreamble"));
                        break;
 
                case TC_HTMLPREAMBLE:
-                       htmlpreamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
+                       htmlpreamble_ = lexrc.getLongString(from_ascii("EndPreamble"));
                        break;
 
                case TC_HTMLSTYLES:
-                       htmlstyles_ = from_utf8(lexrc.getLongString("EndStyles"));
+                       htmlstyles_ = lexrc.getLongString(from_ascii("EndStyles"));
                        break;
 
                case TC_HTMLTOCSECTION:
@@ -630,15 +641,15 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        break;
 
                case TC_ADDTOPREAMBLE:
-                       preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
+                       preamble_ += lexrc.getLongString(from_ascii("EndPreamble"));
                        break;
 
                case TC_ADDTOHTMLPREAMBLE:
-                       htmlpreamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
+                       htmlpreamble_ += lexrc.getLongString(from_ascii("EndPreamble"));
                        break;
 
                case TC_ADDTOHTMLSTYLES:
-                       htmlstyles_ += from_utf8(lexrc.getLongString("EndStyles"));
+                       htmlstyles_ += lexrc.getLongString(from_ascii("EndStyles"));
                        break;
 
                case TC_PROVIDES: {
@@ -755,9 +766,35 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        error = !readCiteFormat(lexrc);
                        break;
 
+               case TC_CITEFRAMEWORK:
+                       lexrc.next();
+                       citeframework_ = rtrim(lexrc.getString());
+                       break;
+
+               case TC_MAXCITENAMES:
+                       lexrc.next();
+                       maxcitenames_ = size_t(lexrc.getInteger());
+                       break;
+
                case TC_DEFAULTBIBLIO:
-                       if (lexrc.next())
-                               cite_default_biblio_style_ = rtrim(lexrc.getString());
+                       if (lexrc.next()) {
+                               vector<string> const dbs =
+                                       getVectorFromString(rtrim(lexrc.getString()), "|");
+                               vector<string>::const_iterator it  = dbs.begin();
+                               vector<string>::const_iterator end = dbs.end();
+                               for (; it != end; ++it) {
+                                       if (!contains(*it, ':')) {
+                                               vector<string> const enginetypes =
+                                                       getVectorFromString(opt_enginetype_, "|");
+                                               for (string const &s: enginetypes)
+                                                       cite_default_biblio_style_[s] = *it;
+                                       } else {
+                                               string eng;
+                                               string const db = split(*it, eng, ':');
+                                               cite_default_biblio_style_[eng] = db;
+                                       }
+                               }
+                       }
                        break;
 
                case TC_FULLAUTHORLIST:
@@ -1013,30 +1050,85 @@ bool TextClass::readCiteEngine(Lexer & lexrc)
                        getout = true;
                        continue;
                }
-               string cmd;
                CitationStyle cs;
                char ichar = def[0];
                if (ichar == '#')
                        continue;
-               if (ichar == 'C') {
+               if (isUpperCase(ichar)) {
                        cs.forceUpperCase = true;
-                       def[0] = 'c';
+                       def[0] = lowercase(ichar);
                }
 
+               /** For portability reasons (between different
+                *  cite engines such as natbib and biblatex),
+                *  we distinguish between:
+                *  1. The LyX name as output in the LyX file
+                *  2. Possible aliases that might fall back to
+                *     the given LyX name in the current engine
+                *  3. The actual LaTeX command that is output
+                *  (2) and (3) are optional.
+                *  Also, the GUI string for the starred version can
+                *  be changed
+                *  The syntax is:
+                *  LyXName|alias,nextalias*<!stardesc!stardesctooltip>[][]=latexcmd
+                */
+               enum ScanMode {
+                       LyXName,
+                       Alias,
+                       LaTeXCmd,
+                       StarDesc
+               };
+
+               ScanMode mode = LyXName;
+               ScanMode oldmode = LyXName;
+               string lyx_cmd;
+               string alias;
+               string latex_cmd;
+               string stardesc;
                size_t const n = def.size();
                for (size_t i = 0; i != n; ++i) {
                        ichar = def[i];
-                       if (ichar == '*')
-                               cs.fullAuthorList = true;
+                       if (ichar == '|')
+                               mode = Alias;
+                       else if (ichar == '=')
+                               mode = LaTeXCmd;
+                       else if (ichar == '<') {
+                               oldmode = mode;
+                               mode = StarDesc;
+                       } else if (ichar == '>')
+                               mode = oldmode;
+                       else if (mode == LaTeXCmd)
+                               latex_cmd += ichar;
+                       else if (mode == StarDesc)
+                               stardesc += ichar;
+                       else if (ichar == '$')
+                               cs.hasQualifiedList = true;
+                       else if (ichar == '*')
+                               cs.hasStarredVersion = true;
                        else if (ichar == '[' && cs.textAfter)
                                cs.textBefore = true;
                        else if (ichar == '[')
                                cs.textAfter = true;
-                       else if (ichar != ']')
-                               cmd += ichar;
+                       else if (ichar != ']') {
+                               if (mode == Alias)
+                                       alias += ichar;
+                               else
+                                       lyx_cmd += ichar;
+                       }
                }
-
-               cs.cmd = cmd;
+               cs.name = lyx_cmd;
+               cs.cmd = latex_cmd.empty() ? lyx_cmd : latex_cmd;
+               if (!alias.empty()) {
+                       vector<string> const aliases = getVectorFromString(alias);
+                       for (string const &s: aliases)
+                               cite_command_aliases_[s] = lyx_cmd;
+               }
+               vector<string> const stardescs = getVectorFromString(stardesc, "!");
+               int size = stardesc.size();
+               if (size > 0)
+                       cs.stardesc = stardescs[0];
+               if (size > 1)
+                       cs.startooltip = stardescs[1];
                if (type & ENGINE_TYPE_AUTHORYEAR)
                        cite_styles_[ENGINE_TYPE_AUTHORYEAR].push_back(cs);
                if (type & ENGINE_TYPE_NUMERICAL)
@@ -1155,7 +1247,7 @@ bool TextClass::readFloat(Lexer & lexrc)
 
        string ext;
        string htmlattr;
-       string htmlstyle;
+       docstring htmlstyle;
        string htmltag;
        string listname;
        string listcommand;
@@ -1259,7 +1351,7 @@ bool TextClass::readFloat(Lexer & lexrc)
                        break;
                case FT_HTMLSTYLE:
                        lexrc.next();
-                       htmlstyle = lexrc.getLongString("EndHTMLStyle");
+                       htmlstyle = lexrc.getLongString(from_ascii("EndHTMLStyle"));
                        break;
                case FT_HTMLTAG:
                        lexrc.next();
@@ -1330,18 +1422,6 @@ bool TextClass::readOutlinerName(Lexer & lexrc)
 }
 
 
-docstring TextClass::outlinerName(std::string const & type) const
-{
-       std::map<std::string,docstring>::const_iterator const it
-               = outliner_names_.find(type);
-       if (it == outliner_names_.end()) {
-               LYXERR0("Missing OutlinerName for " << type << "!");
-               return from_utf8(type);
-       } else
-               return it->second;
-}
-
-
 string const & TextClass::prerequisites(string const & sep) const
 {
        if (contains(prerequisites_, ',')) {
@@ -1585,6 +1665,7 @@ Layout TextClass::createBasicLayout(docstring const & name, bool unknown) const
 
 DocumentClassPtr getDocumentClass(
                LayoutFile const & baseClass, LayoutModuleList const & modlist,
+               LayoutModuleList const & celist,
                bool const clone)
 {
        DocumentClassPtr doc_class =
@@ -1623,6 +1704,42 @@ DocumentClassPtr getDocumentClass(
                        frontend::Alert::warning(_("Read Error"), msg);
                }
        }
+
+       LayoutModuleList::const_iterator cit = celist.begin();
+       LayoutModuleList::const_iterator cen = celist.end();
+       for (; cit != cen; ++cit) {
+               string const ceName = *cit;
+               LyXCiteEngine * ce = theCiteEnginesList[ceName];
+               if (!ce) {
+                       docstring const msg =
+                                               bformat(_("The cite engine %1$s has been requested by\n"
+                                               "this document but has not been found in the list of\n"
+                                               "available engines. If you recently installed it, you\n"
+                                               "probably need to reconfigure LyX.\n"), from_utf8(ceName));
+                       if (!clone)
+                               frontend::Alert::warning(_("Cite Engine not available"), msg);
+                       continue;
+               }
+               if (!ce->isAvailable() && !clone) {
+                       docstring const prereqs = from_utf8(getStringFromVector(ce->prerequisites(), "\n\t"));
+                       docstring const msg =
+                               bformat(_("The cite engine %1$s requires a package that is not\n"
+                                       "available in your LaTeX installation, or a converter that\n"
+                                       "you have not installed. LaTeX output may not be possible.\n"
+                                       "Missing prerequisites:\n"
+                                               "\t%2$s\n"
+                                       "See section 3.1.2.3 (Modules) of the User's Guide for more information."),
+                               from_utf8(ceName), prereqs);
+                       frontend::Alert::warning(_("Package not available"), msg, true);
+               }
+               FileName layout_file = libFileSearch("citeengines", ce->getFilename());
+               if (!doc_class->read(layout_file, TextClass::CITE_ENGINE)) {
+                       docstring const msg =
+                                               bformat(_("Error reading cite engine %1$s\n"), from_utf8(ceName));
+                       frontend::Alert::warning(_("Read Error"), msg);
+               }
+       }
+
        return doc_class;
 }
 
@@ -1692,10 +1809,12 @@ Layout const & DocumentClass::htmlTOCLayout() const
 }
 
 
-string const DocumentClass::getCiteFormat(CiteEngineType const & type,
-       string const & entry, string const & fallback) const
+string const DocumentClass::getCiteFormat(CiteEngineType const & type,
+       string const & entry, bool const punct, string const & fallback) const
 {
-       static string default_format = "{%author%[[%author%, ]][[{%editor%[[%editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}.";
+       string default_format = "{%fullnames:author%[[%fullnames:author%, ]][[{%fullnames:editor%[[%fullnames:editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}";
+       if (punct)
+               default_format += ".";
 
        map<CiteEngineType, map<string, string> >::const_iterator itype = cite_formats_.find(type);
        if (itype == cite_formats_.end())
@@ -1705,6 +1824,8 @@ string const & DocumentClass::getCiteFormat(CiteEngineType const & type,
                it = itype->second.find(fallback);
        if (it == itype->second.end())
                return default_format;
+       if (punct)
+               return it->second + ".";
        return it->second;
 }
 
@@ -1732,7 +1853,7 @@ vector<string> const DocumentClass::citeCommands(
        vector<string> cmds;
        for (; it != end; ++it) {
                CitationStyle const cite = *it;
-               cmds.push_back(cite.cmd);
+               cmds.push_back(cite.name);
        }
        return cmds;
 }