Added templates
[bibliodb.git] / CiteOutput.php
blob6c80041fb20024a71227e8fe57009725aa8d1e33
1 <?php
2 require_once("view/CiteView.php");
3 class CiteOutput{
4 //enforce singleton
5 private $types=array();
6 final private function __clone() {}
7 final private function __construct() {
8 $this->addFilter("html","OutputHtml");
9 $this->addFilter("latex","OutputLatex");
12 final private static function getInstance()
14 static $instance = null;
16 if (null === $instance) {
17 $instance = new CiteOutput();
19 return $instance;
22 public function factory($arg=""){
23 $instance=self::getInstance();
24 $type=CiteConfig::getValue("output_filter");
25 if(array_key_exists($type,$instance->types)){
26 return new $instance->types[$type]($arg);
27 }else{
28 throw new Exception("Output filter \"$type\" doesn´t exist");
31 function addFilter($name,$class){
32 $this->types[$name]=$class;
36 class OutputFilter{
37 protected $blocks=array();
38 protected $s;
39 protected $escape=true;
40 protected $nospace=false;
41 protected $spaces=false;
42 protected $filters=array();
43 protected $functions=array();
44 function __construct($string){
45 $this->s=$this->escape($string);
46 $this->addFunction("lowercase","TextLowercase");
47 $this->addFunction("uppercase","TextUppercase");
48 $this->addFunction("capitalize-first","TextCapitalizeFirst");
49 $this->addFunction("title","TextTitleCase");
52 protected function addFunction($name,$class){
53 $this->functions[$name]=new $class;
56 protected function add($s){
57 $space="";
58 if(strlen($this->s)>0){
59 if(substr($this->s,-1)!==" " && substr($this->s,0)!==" " && !$this->nospace && !$this->spaces)$space=" ";
61 $this->s.=$space.$s;
62 $this->nospace=false;
63 return $this;
66 public function noSpaces(){$this->spaces=true;return $this;}
67 public function spaces(){$this->spaces=false;return $this;}
69 protected function escape($s){
70 if(!$this->escape)return $s;
71 return htmlspecialchars($s);
73 public function noEscape(){$this->escape=false;return $this;}
74 protected function stringGet($s){
76 if($s){$s= $this->escape($s);}
77 else{
78 $s=$this->s;
79 $this->s="";
81 return $s;
83 protected function tag($tag,$s,$params=array()){
84 return $this->startTag($tag,$params).$this->escape($s).$this->closeTag($tag,$params);
87 protected function startTag($tag,$params){
88 $p="";
89 foreach($params as $key=>$value){
90 $p.=" $key=\"".$this->escape($value)."\"";
92 return "<$tag$p>";
94 protected function closeTag($tag,$params){
95 return "</$tag>";
97 public function out(){
98 CiteView::out($this->s);
99 return $this;
101 public function get(){
102 return $this->s;
104 public function textFunction($function, $s=false){
105 $s=$this->stringGet($s); //if parameter $s is empty, then $s will be $this->s
106 if(array_key_exists($function,$this->functions)){
107 $s= $this->functions[$function]->execute($s);
109 $this->add($s);
110 return $this;
113 public function template($format,$string=false){
114 $string=$this->stringGet($string);
115 if(array_key_exists($format,$this->formats))$this->add(sprintf($this->formats[$format],$string));
116 else throw new Exception("Output template $format doesn´t exist");
117 return $this;
120 public function startBlock($block){
121 $tag=array_key_exists($block,$this->blocks)?$this->blocks[$block]:null;
122 $this->add($this->startTag($tag,array()));
123 return $this;
125 public function closeBlock($block){
126 $tag=array_key_exists($block,$this->blocks)?$this->blocks[$block]:null;
127 $this->add($this->closeTag($tag,array()));
128 return $this;
132 //ToDo: More TextCase handlers. Unimplemented:
133 //"capitalize-first": capitalizes the first character; the case of other characters is not affected
134 //"capitalize-all": capitalizes the first character of every word; other characters are displayed lowercase
135 //"sentence": displays text in sentence case ("sentence style")
137 class TextLowercase{public function execute($s){return mb_convert_case($s,MB_CASE_LOWER,"UTF-8");}}
138 class TextUppercase{public function execute($s){return mb_convert_case($s,MB_CASE_UPPER,"UTF-8");}}
139 class TextCapitalizeFirst {public function execute($s){return mb_convert_case($s,MB_CASE_TITLE,"UTF-8");}}
140 class TextTitleCase{public function execute($s){return mb_convert_case($s,MB_CASE_TITLE,"UTF-8");}}
144 interface BaseOutput{
145 function bold($s);
146 function italics($s);
147 function lineBreak();
148 function text($s);
149 function template($format,$s=false);
151 class OutputHtml extends OutputFilter implements BaseOutput{
152 protected $formats=array(
153 "bibstart"=> "<div class=\"csl-bib-body\">\n%s",
154 "bibend"=> "%s</div>",
155 "@font-style/italic"=> "<i>%s</i>",
156 "@font-style/oblique"=> "<em>%s</em>",
157 "@font-style/normal"=> "<span style=\"font-style=>normal;\">%s</span>",
158 "@font-variant/small-caps"=> "<span style=\"font-variant=>small-caps;\">%s</span>",
159 "@font-variant/normal"=> "%s",
160 "@font-weight/bold"=> "<b>%s</b>",
161 "@font-weight/normal"=> "<span style=\"font-weight=>normal;\">%s</span>",
162 "@font-weight/light"=> "%s",
163 "@text-decoration/none"=> "<span style=\"text-decoration=>none;\">%s</span>",
164 "@text-decoration/underline"=> "<span style=\"text-decoration=>underline;\">%s</span>",
165 "@vertical-align/baseline"=> "%s",
166 "@vertical-align/sup"=> "<sup>%s</sup>",
167 "@vertical-align/sub"=> "<sub>%s</sub>",
168 "@bibliography/entry"=> "<div class=\"csl-entry\">%s</div>\n"
170 protected $blocks=array("citation"=>"quote");
171 public function bold($s){
172 $this->add($this->tag("strong",$s));
173 return $this;
175 public function italics($s){
176 $this->add($this->tag("i",$s));
177 return $this;
179 public function lineBreak(){
180 $this->add("<br />\n");
181 return $this;
184 public function text($s){
185 $this->add($this->escape($s));
186 return $this;
191 class OutputLatex extends OutputFilter implements BaseOutput{
192 protected $blocks=array("citation"=>"cite");
193 protected $formats=array("bibstart"=> "\\begin{thebibliography}\n%s",
194 "bibend"=> "%s\\end{thebibliography}\n",
195 "@font-style/italic"=> "\\textit{%s}",
196 "@font-style/oblique"=> "\\emph{%s}",
197 "@font-style/normal"=> "\\textnormal{%s}</span>",
198 "@font-variant/small-caps"=> "\\textsc{%s}",
199 "@font-variant/normal"=> "\\textnormal{%s}",
200 "@font-weight/bold"=> "\\textbf{%s}",
201 "@font-weight/normal"=> "\\textnormal{%s}",
202 "@font-weight/light"=> "%s",
203 "@text-decoration/none"=> "\\texnormal{%s}",
204 "@text-decoration/underline"=> "\\underline{%s}",
205 "@vertical-align/baseline"=> "%s",
206 "@vertical-align/sup"=> "\\textsuperscript{%s}",
207 "@vertical-align/sub"=> "\\ensuremath{_{\\textrm{\\scriptsize %s}}}",
208 "@bibliography/entry"=> "\n\\bibitem %s\n",
211 protected function startTag($tag,$params){
212 return "\\$tag{";
214 protected function closeTag($tag,$params){
215 return "}";
217 public function bold($s){
218 $this->add($this->tag("textbf",$s));
219 return $this;
221 public function italics($s){
222 $this->add($this->tag("textit",$s));
223 return $this;
225 public function lineBreak(){
226 $this->add("\\\\\n");
227 return $this;
229 public function text($s){
230 $this->add($this->escape($s));
231 return $this;
233 public function startBlock($block){
234 $tag=array_key_exists($block,$this->blocks)?$this->blocks[$block]:null;
235 $this->add("\n\\begin{".$tag."}\n");
236 $this->nospace=true;
237 return $this;
239 public function closeBlock($block){
240 $this->nospace=true;
241 $tag=array_key_exists($block,$this->blocks)?$this->blocks[$block]:null;
242 $this->add("\n\\end{".$tag."}\n");
243 return $this;