00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef XDKBIB_FORMATTER_H
00019 #define XDKBIB_FORMATTER_H
00020
00021 #if HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024
00025 #include <xdkbibtex/value.h>
00026 #include <xdkbibtex/entry.h>
00027 #include <iostream>
00028
00029 namespace xdkbib
00030 {
00031 class Entry;
00032 class File;
00033 class Author;
00034 class AuthorList;
00035 class Text;
00036
00037
00038
00039 class Formatter
00040 {
00041 public:
00042 virtual ~Formatter();
00043 virtual std::ostream& operator()(std::ostream& s,const Entry* e) const = 0;
00044 virtual std::ostream& operator()(std::ostream& s,const File* e) const = 0;
00045 virtual std::ostream& operator()(std::ostream& s,
00046 const Author* a) const = 0;
00047 virtual std::ostream& operator()(std::ostream& s,
00048 const AuthorList* a) const = 0;
00049 virtual std::ostream& operator()(std::ostream& s, const Text* t) const = 0;
00050 };
00051
00052
00053
00054 class BibTeX : public Formatter
00055 {
00056 public:
00057 BibTeX();
00058 virtual std::ostream& operator()(std::ostream& s,const Entry* e) const;
00059 virtual std::ostream& operator()(std::ostream& s,const File* e) const;
00060 virtual std::ostream& operator()(std::ostream& s,const Author* a) const;
00061 virtual std::ostream& operator()(std::ostream& s,
00062 const AuthorList* a) const;
00063 virtual std::ostream& operator()(std::ostream& s, const Text* t) const;
00064 template <class O>
00065 std::ostream& operator()(std::ostream& s,O first,O last) const;
00066 private:
00067 void movePos(std::ostream&,unsigned int) const;
00068 mutable int indent_;
00069 mutable int pos_;
00070 mutable bool isFirstWord_;
00071 };
00072
00073 template <class F>
00074 std::pair<const Entry*,F> format(const Entry& e)
00075 {
00076 return std::make_pair(&e,F());
00077 }
00078 template <class F>
00079 std::pair<const File*,F> format(const File& f)
00080 {
00081 return std::make_pair(&f,F());
00082 }
00083 template <class F>
00084 std::pair<const Author*,F> format(const Author& a)
00085 {
00086 return std::make_pair(&a,F());
00087 }
00088 template <class F>
00089 std::pair<const AuthorList*,F> format(const AuthorList& l)
00090 {
00091 return std::make_pair(&l,F());
00092 }
00093 template <class F>
00094 std::pair<const Text*,F> format(const Text& t)
00095 {
00096 return std::make_pair(&t,F());
00097 }
00098 template <class F>
00099 std::ostream& operator<<(std::ostream& s,
00100 const std::pair<const Entry*,F>& p)
00101 {
00102 return p.second(s,p.first);
00103 }
00104 template <class F>
00105 std::ostream& operator<<(std::ostream& s,
00106 const std::pair<const File*,F>& p)
00107 {
00108 return p.second(s,p.first);
00109 }
00110 template <class F>
00111 std::ostream& operator<<(std::ostream& s,
00112 const std::pair<const Author*,F>& p)
00113 {
00114 return p.second(s,p.first);
00115 }
00116 template <class F>
00117 std::ostream& operator<<(std::ostream& s,
00118 const std::pair<const AuthorList*,F>& p)
00119 {
00120 return p.second(s,p.first);
00121 }
00122 template <class F>
00123 std::ostream& operator<<(std::ostream& s,
00124 const std::pair<const Text*,F>& p)
00125 {
00126 return p.second(s,p.first);
00127 }
00128
00129
00130
00131 template <class O>
00132 std::ostream&
00133 BibTeX::operator()(std::ostream& s,O first,O last) const
00134 {
00135 for (O jter = first;jter != last;++jter)
00136 {
00137 if (jter != first)
00138 {
00139 s<<" # ";
00140 movePos(s,3);
00141 }
00142 std::string prefix="";
00143 std::string suffix="";
00144 switch (jter->type())
00145 {
00146 case Braced: prefix="{";suffix="}";break;
00147 case Quoted: prefix=suffix="\"";break;
00148 case Number:
00149 case String:
00150 break;
00151 }
00152 Text text;
00153 text.readFrom(jter->content());
00154 s<<prefix;
00155 indent_ += prefix.size();
00156 operator()(s,&text);
00157 indent_ -= prefix.size();
00158 s<<suffix;
00159 }
00160 return s;
00161 }
00162 }
00163
00164 #endif // XDKBIB_FORMATTER_H