5 private $macros=array();
7 private $citation=null;
8 private $bibliography=null;
11 private $types=array();
12 final private function __clone() {}
13 final private function __construct() {
14 $this->addFilter("base","CiteprocField");
15 $this->addFilter("names","CiteprocNames");
16 $this->addFilter("text","CSLText");
17 $this->addFilter("number","CSLNumber");
18 $this->addFilter("group","CSLGroup");
19 $this->addFilter("choose","CSLChoose");
20 $this->citation
=new CSLCitation($this);
21 $this->bibliography
=new CSLBibliography($this);
25 final private static function getInstance()
27 static $instance = null;
28 if (null === $instance) {
29 $instance = new self();
34 public function style($name){
35 $instance=self
::getInstance();
36 $instance->name
=$name;
39 public function citation(){
40 $instance=self
::getInstance();
41 return $instance->citation
;
43 public function bibliography(){
44 $instance=self
::getInstance();
45 return $instance->bibliography
;
48 public function macro($macro_name){
49 $instance=self
::getInstance();
50 $macro=new CSLMacro($instance);
51 $instance->macros
[$macro_name]=$macro;
54 public function useMacro($macro_name=""){
55 $instance=self
::getInstance();
56 if(array_key_exists($macro_name,$instance->macros
))
57 return $instance->macros
[$macro_name]->get();
60 public function lang($lang){
61 $instance=self
::getInstance();
62 $instance->lang
=$lang;
65 public function useTerm($term, $lang){
66 $instance=self
::getInstance();
67 $lang=$lang?
$lang:$instance->lang
;
70 public function cite(){
71 //ToDo: Generate citekey
72 $instance=self
::getInstance();
73 return $instance->citation
->get();
75 public function printBibliography($records=false){
76 $instance=self
::getInstance();
77 CiteData
::records($records);
78 $out=CiteOutput
::factory()->noEscape()->template("bibstart");
79 while(CiteData
::current()===true){
80 $cite=$instance->cite();
81 $bib=$instance->getBibRecord();
82 $out->text($instance->formatBibRecord($cite,$bib));
84 Profiller
::speed("Položka bibliografie");
86 $out->template("bibend");
90 public function formatBibRecord($citation, $record){
91 return CiteOutput
::factory()->noEscape()->text("$record")->template("@bibliography/entry")->get();
93 public function getBibRecord(){
94 $instance=self
::getInstance();
95 return $instance->bibliography
->get();
96 //$out=CiteOutput::factory()->noEscape();
97 //foreach($instance->fields as $field){
98 // $out->text($field->get());
100 //return $out->get();
102 public function field($type){
103 $instance=self
::getInstance();
104 if(array_key_exists($type,$instance->types
)){
105 $c=new $instance->types
[$type]($instance);
106 $instance->fields
[]=$c;
109 throw new Exception("Output filter \"$type\" doesn´t exist");
113 public function getField($type,$parent){
114 $instance=self
::getInstance();
115 if(array_key_exists($type,$instance->types
)){
116 $c=new $instance->types
[$type]($parent);
117 //$instance->fields[]=$c;
120 throw new Exception("Output filter \"$type\" doesn´t exist");
123 function addFilter($name,$class){
124 $this->types
[$name]=$class;
130 protected $value=null;
131 protected $fields=array();
132 protected $parent_class=null;
133 public $variable=null;
134 protected $delimiter=",";
135 protected $actions=array();
136 protected $form=null;
137 protected $term=null;
138 protected $lang=null;
140 function __construct($parent){
141 $this->parent_class
=$parent;
143 public function setData($data){
147 public function setter($variable,$value){
148 $this->$variable=$value;
151 public function variable($name){
152 $this->variable
=$name;
155 public function macro($macro_name){
156 $this->macro
=$macro_name;
159 public function term($term_name,$lang=false){
160 //$lang = language of cited document
161 $this->term
=$term_name;
165 public function value($value){
169 public function form($form="long"){
170 //form = long / short / verb / verb-short / symbol
174 protected function getData($field=null){
176 return CiteData
::getList($field);
177 }else if($this->macro
!=null){
178 //echo "Použiju makro<br />";
179 return CSL
::useMacro($this->macro
);
180 }else if($this->data
){
181 return $this->useFormat($this->data
);
182 }else if($this->value
){
184 }else if($this->term
){
185 return CSL
::useTerm($this->term
, $this->lang
);
187 echo "Nic z toho<br />";
191 public function end(){
192 //print_r($this->parent_class);
193 return $this->parent_class
;
195 protected function useFormat($data){
196 return implode($this->delimiter
,$data);
198 public function field($type){
199 $c=CSL
::getField($type,$this);
206 class CSLTop
extends CiteprocField
{
207 protected $sort=null;
208 protected $layout=null;
209 public function __construct($parent){
210 parent
::__construct($parent);
211 $this->sort
=new CSLSort($this);
212 $this->layout
=new CSLLayout($this);
214 public function sort(){return $this->sort
;}
215 public function layout(){return $this->layout
;}
216 public function get(){return $this->layout
->get();}
217 public function getSortOptions(){$this->sort
->get();}
220 class CSLCitation
extends CSLTop
{
221 public function get(){
222 $author=array_shift($this->getData("author"));
223 $author=$author["family"].", ".$author["given"];
224 $year=$this->getData("date");
225 $key=CiteData
::getCiteKey();
226 return "[$author($year)]{{$key}}";
230 class CSLBibliography
extends CSLTop
{
231 public function get(){
232 return $this->layout
->get();
235 class CSLSort
extends CiteprocField
{
236 public function get(){
237 return $this->layout
->get();
240 class CSLSubFields
extends CiteprocField
{
241 public function get(){
242 $out=CiteOutput
::factory()->noEscape();
243 foreach($this->fields
as $field){
244 $out->text($field->get());
249 class CSLLayout
extends CSLSubFields
{
251 class CiteprocField
extends CSLBase
{
254 //public $macros=array();
256 protected $font_style=array("normal"=>"@font-style/normal","italic"=>"@font-style/italic","oblique"=>"@font-style/oblique");
257 protected $font_variant=array("normal"=>"@font-variant/normal","small-caps"=>"@font-variant/small-caps");
258 protected $font_weight=array("normal"=>"@font-weight/normal","bold"=>"@font-weight/bold","light"=>"@font-weight/light");
259 protected $text_decoration=array("none"=>"@text-decoration/none","underline"=>"@text-decoration/underline");
260 protected $vertical_align=array("baseline"=>"@vertical-align/baseline","sup"=>"@vertical-align/sup","sub"=>"@vertical-align/sub");
261 protected $styles=array();
263 protected $text_case="";
265 public function __construct($parent){
266 parent
::__construct($parent);
267 $this->prefix($this->parent_class
->prefix
)
268 ->suffix($this->parent_class
->suffix
);
271 public function prefix($s){
275 public function suffix($s){
280 public function fontStyle($style){return $this->style($this->font_style
,$style);}
281 public function fontVariant($style){return $this->style($this->font_variant
,$style);}
282 public function fontWeight($style){return $this->style($this->font_weight
,$style);}
283 public function textDecoration($style){return $this->style($this->text_decoration
,$style);}
284 public function verticalAlign($style){return $this->style($this->vertical_align
,$style);}
285 public function style($stylearray,$style){
286 if(array_key_exists($style, $stylearray)){
287 $this->styles
[]=$stylearray[$style];
291 public function textCase($case){$this->text_case
=$case;return $this;}
293 protected function useStyle($s){
294 $format=CiteOutput
::factory($s)->textFunction($this->text_case
);
295 foreach($this->styles
as $style)$format->template($style);
296 return $format->get();
298 //protected function getData(){
299 // return CiteData::getField($this->variable);
301 protected function usePrefix(){return $this->prefix
;}
302 protected function useSuffix($s=null){
303 $last_char=substr(trim($s),-1);
304 return ($last_char==$this->suffix
)?
"":$this->suffix
;
306 public function get(){
307 $data= $this->getData($this->variable
);
309 return $this->usePrefix().$this->useStyle($data).$this->useSuffix($data);
315 public function printError(Exception
$e){
316 echo "<div style=\"border:1px solid black;color:red;\">".error_message
.$e->getMessage()."</div>\n";
320 class CiteprocList
extends CiteprocField
{
321 protected $limit=false;
322 protected $limit_use=false;
324 public function limit($limit){
328 public function limitUse($use){
329 $this->limit_use
=$use;
332 protected function processField($field,$last=false){
333 return implode(", ",$field);
335 public function get(){
337 $data=CiteData
::getList($this->variable
);
338 $data_len=count($data);
339 if($data_len==0)return false;
340 $max=$this->limit_use?
$this->limit_use
:$this->limit
;
341 $counter=$this->limit?
$this->limit
:$data_len;
342 $counter=($counter >= $data_len)?
$data_len:$max;
343 $return_value=$this->usePrefix();
344 //CiteOutput::factory("Použijeme $counter položek. Maximum je $max, $položek v databázi bylo $data_len")->out();
346 for($i=0;$i<$counter;$i++
){
347 //$return_value.=$this->processField($data[$i]);
348 $last=($i==($counter-2))?
1:0;
349 $last=($i==($counter-1))?
-1:$last;
350 $return_value.=$this->processField($data[$i],$last);
352 //if(count($fields)>1){
353 // $delim=array_slice($fields,0,count($fields)-1);
354 // $last=array_slice($fields,-1);
355 // $return_value.=implode($this->useDelimiter(),$delim).$this->use
357 $return_value.=$this->useSuffix($return_value);
358 return $return_value;
359 //CiteOutput::factory("Použijeme $counter položek. Maximum je $max, $položek v databázi bylo $data_len")->out();
363 CiteOutput
::factory("There is some problem with data: ".$e->getMessage())->out();;
370 class CiteprocDataSet
extends CiteprocField
{
372 public function setData($data){
376 protected function getData($variable=null){
377 return $this->useFormat($this->data
);
381 //CitationStyle Names element
382 class CiteprocNames
extends CiteprocList
{
385 protected $names=null;
386 public function __construct($parent){
387 parent
::__construct($parent);
388 $this->names
=new CiteprocName($this);
390 protected function processField($data,$last=false){
391 $this->names
->setData($data);
394 $add=$this->names
->useDelimiter();
396 $add=$this->names
->useDelimiterPrecedesLast();
398 //CiteOutput::factory("Oddělovač $add")->lineBreak()->out();
399 return "{$this->names->get()}$add";
401 public function name(){
406 class CiteprocName
extends CiteprocDataSet
{
407 //Musí být zabalen ve třídě CiterpocNames
409 private $parts=array();
410 protected $delimiter=",";
411 protected $_and=" & ";
412 protected $precedes_last="never";
414 public function useDelimiter(){ return $this->delimiter
;}
415 public function useAnd(){return $this->_and
;}
416 public function useDelimiterPrecedesLast(){
417 switch($this->precedes_last
){
419 return $this->delimiter
.$this->_and
;
426 public function namePart($part_name){
427 $this->parts
[$part_name]=new CiteprocNamePart($this);
428 return $this->parts
[$part_name];
430 public function delimiter($s){
434 public function delimiterAnd($s){
438 protected function usePart($part,$data){
439 if(array_key_exists($part,$data)){
440 if(array_key_exists($part,$this->parts
)){
441 return $this->parts
[$part]->setData($data)
444 //return $this->parts[$part]->get();
452 protected function useFormat($part){
453 $parts=array("family",", ","given");
455 foreach($parts as $element){
456 $return_value.=$this->usePart($element,$part);
458 return $return_value;
459 //return implode(", ",array($part[family],$part["given"]));
461 //public function get(){
462 // return $this->usePrefix().$this->useStyle($this->getData()).$this->useSuffix();
465 class CiteprocNamePart
extends CiteprocDataSet
{
466 public function getData($variable){
467 return $this->data
[$variable];
472 class CSLMacro
extends CSLSubFields
{}
473 class CSLText
extends CiteprocField
{
475 class CSLNumber
extends CiteprocField
{}
476 class CSLGroup
extends CSLSubFields
{
477 public function get(){
478 $out=CiteOutput
::factory()->noEscape();
482 foreach($this->fields
as $field){
483 $result=$field->get();
484 if($field->variable
OR $field->macro
){
485 $sub_condition=strlen($result)>0?
true:false;
486 $condition=($condition ||
$sub_condition);
491 //$out->text($this->useSuffix());
492 if($condition===false AND $checked_values>0){
495 return $this->usePrefix().$this->useStyle($out->get()).$this->useSuffix();
500 class CSLChoose
extends CiteprocField
{
501 protected $ifs=array();
502 protected $elses=null;
503 public function cslIf(){
504 $if= new CSLIf($this);
508 public function cslElseIf(){
509 return $this->cslIf();
511 public function cslElse(){
512 $else=new CSLIf($this);
516 public function get(){
519 foreach($this->ifs
as $condition){
521 $result=$condition->get();
522 //CiteOutput::factory("Tak a result je $result, průchod $pruchod")->lineBreak()->out();
523 if(strlen($result)>0){
524 $trues[]=array("disambiguate"=>$condition->getDisambiguate(),"content"=>$result);
527 //CiteOutput::factory("Tak a result je $result, průchod $pruchod")->lineBreak()->out();
529 foreach($trues as $disambig){
530 if($disambig["disambiguate"])return $disambig["content"];
532 return $trues[0]["content"];
534 if($this->elses
)return $this->elses
->get();
539 class CSLIf
extends CSLSubFields
{
540 protected $disambiguate=false;
541 protected $conditions=array();
542 protected $matches="all";
543 protected function setCondition($condition_name,$values){
544 $chunks=explode(" ",$values);
545 $this->conditions
[$condition_name]=$chunks;
548 //public function cslIf(){return $this->parent_class->cslIf();}
549 public function cslElseIf(){ return $this->parent_class
->cslElseIf();}
550 public function cslElse(){return $this->parent_class
->cslElse();}
551 public function getDisambiguate(){
552 return $this->disambiguate
;
554 //conditional functions
555 public function disambiguate($disambiguate=true){
556 $this->disambiguate
=$disambiguate;
559 public function isNumeric($variable){return $this->setCondition("IsNumeric",$variable);}
560 public function isUncertainDate($variable){return $this->setCondition("IsUncertain_date",$variable);}
561 public function locator($variable){return $this->setCondition("Locator",$variable);}
562 public function position($variable){
563 //Implementovat v budoucnu, zatím nemá smysl
567 public function type($type){return $this->setCondition("Type",$type);}
569 public function variable($variable){return $this->setCondition("Variable",$variable);}
571 public function match($match="all"){return $this->setter("matches",$match);}
573 protected function testIsNumeric($variable){return is_numeric(CiteData
::getData($variable));}
574 protected function testIsUncertainDate($variable){return false;}
575 protected function testLoacator($variable){return CiteData
::getData("locator")==$variable;}
576 protected function testPosition($position){return false;}
577 protected function testType($type){return CiteData
::getData("type")==$type;}
578 protected function testVariable($variable){return CiteData
::getData($variable)!==null;}
579 protected function logical($conditions){
580 if(count($conditions)==1)return $conditions[0];
581 $sum=$this->matches
=="all"?
true:false;
582 foreach($conditions as $cond){
583 $suma=$cond?
"true":"false";
584 if($this->matches
=="any"){
585 $sum=($sum OR $cond);
587 $sum=($sum AND $cond);
590 return $this->matches
=="none"?
!$sum:$sum;
593 protected function testCondition($condition_name,$values){
595 $condition_method="test$condition_name";
596 foreach($values as $element){
597 $conditions[]=$this->$condition_method($element);
599 return $this->logical($conditions);
602 public function get(){
604 foreach($this->conditions
as $sub_condition=>$values){
605 $condition[]=$this->testCondition($sub_condition,$values);
607 //CiteOutput::factory(implode(" - ",$condition))->lineBreak()->out();
608 if($this->logical($condition))return parent
::get();
609 if(!count($this->conditions
)>0)return parent
::get();