]> git.lyx.org Git - features.git/commitdiff
Introduce a simple macro facility for citation formats. Also introduce
authorRichard Heck <rgheck@comcast.net>
Mon, 29 Mar 2010 20:01:28 +0000 (20:01 +0000)
committerRichard Heck <rgheck@comcast.net>
Mon, 29 Mar 2010 20:01:28 +0000 (20:01 +0000)
simple, translatable units for use in such formats.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33924 a592a061-630c-0410-9148-cb99ea01b6c8

lib/layouts/stdciteformats.inc
po/lyx_pot.py
src/BiblioInfo.cpp
src/BiblioInfo.h
src/TextClass.cpp
src/TextClass.h

index 6247a647fa8f74df045e4b7a1df655eecbf96e83..a5e4dd97a0fb706596f3961b0073a093a58162f5 100644 (file)
@@ -4,12 +4,30 @@
 
 Format 26
 
-CiteFormat 
-       article %author%, "%title%", {!<i>!}%journal%{!</i>!} {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
+CiteFormat
+       # translatable bits
+       _pptext pp.
+       _edtext ed.
+       _voltext vol.
+       _numtext no.
+       _in in
+
+       # macros
+       !pages {%pages%[[, %_pptext% %pages%]]}
+       !authoredit {%author%[[%author%, ]][[{%editor%[[%editor%, %_edtext%, ]]}]]}
+       !volnum {%volume%[[ %_voltext% %volume%]][[{%number%[[%_numtext% %number%]]}]]}
+       !quotetitle "%title%"
+       !emphtitle {!<i>!}%title%{!</i>!}
+       !emphjournal {!<i>!}%journal%{!</i>!}
+
+       !insomething %author%, %!quotetitle%, %_in%{%editor%[[ %editor%, %_edtext%,]]} {!<i>!}%booktitle%{!</i>!}%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%)%!pages%.{%note%[[ %note%]]}
+
+       article %author%, %!quotetitle%, %!emphjournal% {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%)%!pages%.{%note%[[ %note%]]}
        
-       book {%author%[[%author%, ]][[{%editor%[[%editor%, %ed_text%, ]]}]]}{!<i>!}%title%{!</i>!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
+       book %!authoredit%%!emphtitle%%!volnum%{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}
 
-       incollection %author%, \"%title%\", in{%editor%[[ %editor%, %ed_text%,]]} {!<i>!}%booktitle%{!</i>!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%){%pages%[[, pp. %pages%]]}.{%note%[[ %note%]]}
+       incollection %!insomething%
+       inproceedings %!insomething%
 
        thesis %author%, %title% ({%address%[[%address%: ]]}%school%, %year%).{%note%[[ %note%]]}
 End
index 0ac580ad17c88c104ee9211ad2d01dfd6e27f493..842040776d1a47792c2b515ef9b0f81cff4dcef8 100755 (executable)
@@ -92,10 +92,14 @@ def layouts_l10n(input_files, output, base):
     EndI18nPreamble = re.compile(r'\s*End(Lang)|(Babel)Preamble\s*$')
     I18nString = re.compile(r'_\(([^\)]+)\)')
     CounterFormat = re.compile(r'\s*PrettyFormat\s+"?(.*)"?')
-
+    CiteFormat = re.compile(r'\s*CiteFormat')
+    KeyVal = re.compile(r'^\s*_\w+\s+(.*)$')
+    End = re.compile(r'\s*End')
+    
     for src in input_files:
         readingDescription = False
         readingI18nPreamble = False
+        readingCiteFormats = False
         descStartLine = -1
         descLines = []
         lineno = 0
@@ -179,6 +183,18 @@ def layouts_l10n(input_files, output, base):
                 string = res.group(1)
                 writeString(out, src, base, lineno, string)
                 continue
+            res = CiteFormat.search(line)
+            if res != None:
+                readingCiteFormats = True
+            res = End.search(line)
+            if res != None and readingCiteFormats:
+                readingCiteFormats = False
+            if readingCiteFormats:
+                res = KeyVal.search(line)
+                if res != None:
+                    val = res.group(1)
+                    writeString(out, src, base, lineno, val)
+                
     out.close()
 
 
index e7ff51e6d9aa977ab8bfefcf2135c9cb21962d0a..4ee075e596f7e99ec6ca1066951d980ca1a66418 100644 (file)
@@ -395,17 +395,27 @@ namespace {
 
 
 docstring BibTeXInfo::expandFormat(string const & format, 
-               BibTeXInfo const * const xref, bool richtext) const
+               BibTeXInfo const * const xref, Buffer const & buf, 
+               bool richtext) const
 {
+       // incorrect use of macros could put us in an infinite loop
+       static int max_passes = 1000;
        docstring ret; // return value
        string key;
        bool scanning_key = false;
        bool scanning_rich = false;
 
+       int passes = 0;
        string fmt = format;
        // we'll remove characters from the front of fmt as we 
        // deal with them
        while (fmt.size()) {
+               if (passes++ > max_passes) {
+                       LYXERR0("Recursion limit reached while parsing `" 
+                               << format << "'.");
+                       return _("ERROR!");
+               }
+                               
                char_type thischar = fmt[0];
                if (thischar == '%') { 
                        // beginning or end of key
@@ -413,14 +423,27 @@ docstring BibTeXInfo::expandFormat(string const & format,
                                // end of key
                                scanning_key = false;
                                // so we replace the key with its value, which may be empty
-                               docstring const val = getValueForKey(key, xref);
-                               ret += val;
-                               key.clear();
+                               if (key[0] == '!') {
+                                       // macro
+                                       string const val = 
+                                               buf.params().documentClass().getCiteMacro(key);
+                                       fmt = val + fmt.substr(1);
+                                       continue;
+                               } else if (key[0] == '_') {
+                                       // a translatable bit
+                                       string const val = 
+                                               buf.params().documentClass().getCiteMacro(key);
+                                       ret += _(val);
+                               } else {
+                                       docstring const val = getValueForKey(key, xref);
+                                       ret += val;
+                               }
                        } else {
                                // beginning of key
+                               key.clear();
                                scanning_key = true;
                        }
-               } 
+               }
                else if (thischar == '{') { 
                        // beginning of option?
                        if (scanning_key) {
@@ -440,9 +463,9 @@ docstring BibTeXInfo::expandFormat(string const & format,
                                        fmt = newfmt;
                                        docstring const val = getValueForKey(optkey, xref);
                                        if (!val.empty())
-                                               ret += expandFormat(ifpart, xref, richtext);
+                                               ret += expandFormat(ifpart, xref, buf, richtext);
                                        else if (!elsepart.empty())
-                                               ret += expandFormat(elsepart, xref, richtext);
+                                               ret += expandFormat(elsepart, xref, buf, richtext);
                                        // fmt will have been shortened for us already
                                        continue; 
                                }
@@ -453,7 +476,8 @@ docstring BibTeXInfo::expandFormat(string const & format,
                                        continue;
                                }
                        }
-                       // we are here if the '{' was at the end of the format. hmm.
+                       // we are here if '{' was not followed by % or !. 
+                       // So it's just a character.
                        ret += thischar;
                }
                else if (scanning_rich && thischar == '!' 
@@ -497,7 +521,7 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref,
 
        DocumentClass const & dc = buf.params().documentClass();
        string const & format = dc.getCiteFormat(to_utf8(entry_type_));
-       info_ = expandFormat(format, xref, richtext);
+       info_ = expandFormat(format, xref, buf, richtext);
 
        if (!info_.empty())
                info_ = convertLaTeXCommands(info_);
index fffb81c639404ef779864659b803aeaf5b8e1636..05b61f64cbbceebabdf9048fbf67077e33333614 100644 (file)
@@ -117,8 +117,9 @@ private:
        /// material intended only for rich text (HTML) output should be 
        /// wrapped in "{!" and "!}". it will be removed if richtext is
        /// false.
-       docstring expandFormat(std::string const & fmt, 
-                       BibTeXInfo const * const xref, bool richtext) const;
+       docstring expandFormat(std::string const & fmt,
+                       BibTeXInfo const * const xref, 
+                       Buffer const & buf, bool richtext) const;
        /// true if from BibTeX; false if from bibliography environment
        bool is_bibtex_;
        /// the BibTeX key for this entry
index ee4315054714250efac8484d11a0d55e4aa03e33..6bc0bc0c8e65aded738618c509014955e8c4588b 100644 (file)
@@ -863,7 +863,13 @@ void TextClass::readCiteFormat(Lexer & lexrc)
                        break;
                lexrc.eatLine();
                definition = lexrc.getString();
-               cite_formats_[etype] = definition;
+               char initchar = etype[0];
+               if (initchar == '#')
+                       continue;
+               if (initchar == '!' || initchar == '_')
+                       cite_macros_[etype] = definition;
+               else
+                       cite_formats_[etype] = definition;
        }
 }
 
@@ -1361,6 +1367,16 @@ string const & DocumentClass::getCiteFormat(string const & entry_type) const
 }
 
 
+string const & DocumentClass::getCiteMacro(string const & macro) const
+{
+       static string empty;
+       map<string, string>::const_iterator it = cite_macros_.find(macro);
+       if (it != cite_macros_.end())
+               return it->second;
+       return empty;
+}
+
+
 /////////////////////////////////////////////////////////////////////////
 //
 // PageSides
index 52074751bd2aeeea5a9c1d8868df8c3be3f1757f..04816c5b7f5ae3ff0bb73ea35d3a0f8eaaa4cc47 100644 (file)
@@ -306,6 +306,8 @@ protected:
        int max_toclevel_;
        /// Citation formatting information
        std::map<std::string, std::string> cite_formats_;
+       /// Citation macros
+       std::map<std::string, std::string> cite_macros_;
 private:
        ///////////////////////////////////////////////////////////////////
        // helper routines for reading layout files
@@ -429,6 +431,8 @@ public:
        bool hasTocLevels() const;
        ///
        std::string const & getCiteFormat(std::string const & entry_type) const;
+       ///
+       std::string const & getCiteMacro(std::string const & macro) const;
 protected:
        /// Constructs a DocumentClass based upon a LayoutFile.
        DocumentClass(LayoutFile const & tc);