1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SCI; |
4
|
|
|
|
5
|
|
|
use SCI\Bibtex\BibtexProcessor; |
6
|
|
|
use SMW\NamespaceExaminer; |
7
|
|
|
use SMW\ParserParameterProcessor; |
8
|
|
|
use SMW\DataValueFactory; |
9
|
|
|
use SMW\DIProperty; |
10
|
|
|
use SMW\ParserData; |
11
|
|
|
use SMW\Subobject; |
12
|
|
|
use Html; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* #scite: is used the create a citation resource with a reference to be |
16
|
|
|
* accessible wiki-wide trough a unique citation key. |
17
|
|
|
* |
18
|
|
|
* [[CiteRef: ... ]] | [[Citation reference:: ...]] is used to create an in-text |
19
|
|
|
* reference link to a citation resource. |
20
|
|
|
* |
21
|
|
|
* @license GNU GPL v2+ |
22
|
|
|
* @since 1.0 |
23
|
|
|
* |
24
|
|
|
* @author mwjames |
25
|
|
|
*/ |
26
|
|
|
class SciteParserFunction { |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var ParserData |
30
|
|
|
*/ |
31
|
|
|
private $parserData; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var NamespaceExaminer |
35
|
|
|
*/ |
36
|
|
|
private $namespaceExaminer; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var CitationTextTemplateRenderer |
40
|
|
|
*/ |
41
|
|
|
private $citationTextTemplateRenderer; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var MediaWikiNsContentMapper |
45
|
|
|
*/ |
46
|
|
|
private $mediaWikiNsContentMapper; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var BibtexProcessor |
50
|
|
|
*/ |
51
|
|
|
private $bibtexProcessor; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var DataValueFactory |
55
|
|
|
*/ |
56
|
|
|
private $dataValueFactory; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @var boolean |
60
|
|
|
*/ |
61
|
|
|
private $strictParserValidationState = true; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @var array |
65
|
|
|
*/ |
66
|
|
|
private $parameters = []; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @since 1.0 |
70
|
|
|
* |
71
|
|
|
* @param ParserData $parserData |
72
|
|
|
* @param NamespaceExaminer $namespaceExaminer |
73
|
|
|
* @param CitationTextTemplateRenderer $citationTextTemplateRenderer |
74
|
|
|
* @param MediaWikiNsContentMapper $mediaWikiNsContentMapper |
75
|
|
|
* @param BibtexProcessor $bibtexProcessor |
76
|
|
|
*/ |
77
|
18 |
|
public function __construct( ParserData $parserData, NamespaceExaminer $namespaceExaminer, CitationTextTemplateRenderer $citationTextTemplateRenderer, MediaWikiNsContentMapper $mediaWikiNsContentMapper, BibtexProcessor $bibtexProcessor ) { |
78
|
18 |
|
$this->parserData = $parserData; |
79
|
18 |
|
$this->namespaceExaminer = $namespaceExaminer; |
80
|
18 |
|
$this->citationTextTemplateRenderer = $citationTextTemplateRenderer; |
81
|
18 |
|
$this->mediaWikiNsContentMapper = $mediaWikiNsContentMapper; |
82
|
18 |
|
$this->bibtexProcessor = $bibtexProcessor; |
83
|
18 |
|
$this->dataValueFactory = DataValueFactory::getInstance(); |
84
|
18 |
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* @since 1.0 |
88
|
|
|
* |
89
|
|
|
* @param boolean $strictParserValidationState |
90
|
|
|
*/ |
91
|
15 |
|
public function setStrictParserValidationState ( $strictParserValidationState ) { |
92
|
15 |
|
$this->strictParserValidationState = (bool)$strictParserValidationState; |
93
|
15 |
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Identifiers that have a id-property mapping are to be annotated as semantic |
97
|
|
|
* property. The property mapped to an identifier should be maintained |
98
|
|
|
* accordantly with the the expected type it ought to represent |
99
|
|
|
* (e.g. 'url' => 'Has url', with 'Has url' being of [[Has type::URL]]) |
100
|
|
|
* |
101
|
|
|
* Only identifiers used in #scite: that have an appropriate mapping |
102
|
|
|
* will be created as semantic annotation. For example, identifiers important |
103
|
|
|
* for the citation output are not necessarily notable for a semantic |
104
|
|
|
* assignment (e.g. 'pages', 'page reference', or 'available'). |
105
|
|
|
* |
106
|
|
|
* {{#scite:Segon & Booth 2011 |
107
|
|
|
* |type=online |
108
|
|
|
* |author=Segon, M;Booth, C|+sep=; |
109
|
|
|
* |year=2011 |
110
|
|
|
* |title=Bribery: what do Australian managers know and what do they do? |
111
|
|
|
* |journal=Journal of Business Systems, Governance and Ethics |
112
|
|
|
* |volumn=vol. 6, no. 3 |
113
|
|
|
* |pages=15-29 |
114
|
|
|
* |url=http://www.jbsge.vu.edu.au/issues/vol06no3/Segon_&_Booth.pdf |
115
|
|
|
* |available=20 October 2014 |
116
|
|
|
* |template=scite-formatter-online |
117
|
|
|
* }} |
118
|
|
|
* |
119
|
|
|
* OR |
120
|
|
|
* |
121
|
|
|
* {{#scite:Einstein, Podolsky, and Nathan 1935 |
122
|
|
|
* |bibtex=@article{einstein1935can, |
123
|
|
|
* title={Can quantum-mechanical description of physical reality be considered complete?}, |
124
|
|
|
* author={Einstein, Albert and Podolsky, Boris and Rosen, Nathan}, |
125
|
|
|
* journal={Physical review}, |
126
|
|
|
* volume={47}, |
127
|
|
|
* number={10}, |
128
|
|
|
* pages={777}, |
129
|
|
|
* year={1935}, |
130
|
|
|
* publisher={APS} |
131
|
|
|
* } |
132
|
|
|
* |authors=Albert Einstein, Boris Podolsky, Nathan Rosen|+sep=, |
133
|
|
|
* }} |
134
|
|
|
* |
135
|
|
|
* The citation style is determined by the template assigned and stored in |
136
|
|
|
* its own semantic property. To apply for individual formatting rules, use |
137
|
|
|
* |template= |
138
|
|
|
* |
139
|
|
|
* For any free text assignment use, |
140
|
|
|
* |citation text= |
141
|
|
|
* |
142
|
|
|
* @since 1.0 |
143
|
|
|
* |
144
|
|
|
* @param ParserParameterProcessor $parserParameterProcessor |
145
|
|
|
*/ |
146
|
17 |
|
public function doProcess( ParserParameterProcessor $parserParameterProcessor, PreTextFormatter $preTextFormatter = null ) { |
147
|
|
|
|
148
|
17 |
|
if ( !$this->namespaceExaminer->isSemanticEnabled( $this->parserData->getTitle()->getNamespace() ) ) { |
149
|
1 |
|
return $this->createErrorMessageFor( 'sci-scite-parser-not-enabled-namespace' ); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
// Hopefully the bibtex processor will add all required parameters and values |
153
|
16 |
|
if ( $parserParameterProcessor->hasParameter( 'bibtex' ) ) { |
154
|
1 |
|
$this->bibtexProcessor->doProcess( $parserParameterProcessor ); |
155
|
|
|
} |
156
|
|
|
|
157
|
16 |
|
$reference = str_replace( '_', ' ', $parserParameterProcessor->getFirstParameter() ); |
158
|
16 |
|
$type = ''; |
159
|
|
|
|
160
|
|
|
// Explicit reference precedes |
161
|
16 |
|
if ( $parserParameterProcessor->hasParameter( 'reference' ) ) { |
162
|
2 |
|
$reference = $parserParameterProcessor->getParameterValuesFor( 'reference' ); |
|
|
|
|
163
|
2 |
|
$reference = end( $reference ); |
164
|
|
|
} |
165
|
|
|
|
166
|
16 |
|
if ( $reference === '' ) { |
167
|
1 |
|
return $this->createErrorMessageFor( 'sci-scite-parser-no-reference' ); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
// Fixed identifier |
171
|
15 |
|
$parserParameterProcessor->addParameter( |
172
|
15 |
|
'reference', |
173
|
15 |
|
$reference |
174
|
|
|
); |
175
|
|
|
|
176
|
15 |
|
if ( $parserParameterProcessor->hasParameter( 'type' ) ) { |
177
|
14 |
|
$type = $parserParameterProcessor->getParameterValuesFor( 'type' ); |
|
|
|
|
178
|
14 |
|
sort( $type ); |
179
|
14 |
|
$type = end( $type ); |
180
|
|
|
} |
181
|
|
|
|
182
|
15 |
|
$returnText = $this->tryToMatchCitationTextByPrecept( |
183
|
15 |
|
$parserParameterProcessor, |
184
|
15 |
|
$reference, |
185
|
15 |
|
$type |
186
|
|
|
); |
187
|
|
|
|
188
|
15 |
|
$this->addPropertyValuesFor( |
189
|
15 |
|
$parserParameterProcessor, |
190
|
15 |
|
$reference |
191
|
|
|
); |
192
|
|
|
|
193
|
|
|
// If the parser function returns an empty string then the MW Parser will |
194
|
|
|
// add a <br> section leaving the text around a #scite call adding extra |
195
|
|
|
// white space. |
196
|
|
|
// In order to mitigate the issue when several {{#scite:...}} calls are |
197
|
|
|
// placed next to each other, have the first occurrence to mark its |
198
|
|
|
// existence explicitly by outputting an empty paragraph and so avoid a |
199
|
|
|
// <br> element. |
200
|
15 |
|
if ( $returnText === '' && $this->parserData->getOutput()->getExtensionData( 'sci-parserfunction' ) === null ) { |
201
|
14 |
|
$this->parserData->getOutput()->setExtensionData( 'sci-parserfunction', true ); |
202
|
14 |
|
$returnText = '<p></p>'; |
203
|
|
|
} |
204
|
|
|
|
205
|
15 |
|
if ( $parserParameterProcessor->hasParameter( '@show' ) && $preTextFormatter !== null ) { |
206
|
|
|
$returnText = $preTextFormatter->getFormattedSciteFuncFrom( $parserParameterProcessor->getRaw() ) . $returnText; |
207
|
|
|
} |
208
|
|
|
|
209
|
15 |
|
return $returnText; //array( '', 'noparse' => true, 'isHTML' => true ); |
210
|
|
|
} |
211
|
|
|
|
212
|
15 |
|
private function tryToMatchCitationTextByPrecept( ParserParameterProcessor $parserParameterProcessor, $reference, $type = '' ) { |
213
|
|
|
|
214
|
15 |
|
$template = ''; |
215
|
|
|
|
216
|
15 |
|
if ( $this->strictParserValidationState && $type === '' ) { |
217
|
|
|
|
218
|
1 |
|
$parserParameterProcessor->addParameter( |
219
|
1 |
|
DIProperty::TYPE_ERROR, |
220
|
1 |
|
PropertyRegistry::SCI_CITE |
221
|
|
|
); |
222
|
|
|
|
223
|
1 |
|
return $this->createErrorMessageFor( 'sci-scite-parser-no-type', $reference ); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
// An injected text trumps a template |
227
|
14 |
|
if ( $parserParameterProcessor->hasParameter( 'citation text' ) ) { |
228
|
13 |
|
return ''; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
// An explicit template precedes the assignment found for the type |
232
|
2 |
|
if ( $parserParameterProcessor->hasParameter( 'template' ) ) { |
233
|
2 |
|
$template = $parserParameterProcessor->getParameterValuesFor( 'template' ); |
|
|
|
|
234
|
2 |
|
$template = trim( end( $template ) ); |
235
|
2 |
|
} elseif ( $this->mediaWikiNsContentMapper->findTemplateForType( $type ) !== null ) { |
236
|
2 |
|
$template = $this->mediaWikiNsContentMapper->findTemplateForType( $type ); |
237
|
|
|
} |
238
|
|
|
|
239
|
2 |
|
if ( $template !== '' ) { |
240
|
2 |
|
$this->citationTextTemplateRenderer->packFieldsForTemplate( $template ); |
241
|
|
|
|
242
|
|
|
// Fixed identifier |
243
|
2 |
|
$parserParameterProcessor->addParameter( |
244
|
2 |
|
'citation text', |
245
|
2 |
|
$this->citationTextTemplateRenderer->renderFor( $parserParameterProcessor->toArray() ) |
246
|
|
|
); |
247
|
|
|
} elseif ( $this->strictParserValidationState ) { |
248
|
|
|
|
249
|
|
|
$parserParameterProcessor->addParameter( |
250
|
|
|
DIProperty::TYPE_ERROR, |
251
|
|
|
PropertyRegistry::SCI_CITE_TEXT |
252
|
|
|
); |
253
|
|
|
|
254
|
|
|
return $this->createErrorMessageFor( 'sci-scite-parser-no-citation-text', $reference, $type ); |
255
|
|
|
} |
256
|
|
|
|
257
|
2 |
|
return ''; |
258
|
|
|
} |
259
|
|
|
|
260
|
15 |
|
private function addPropertyValuesFor( ParserParameterProcessor $parserParameterProcessor, $reference ) { |
261
|
|
|
|
262
|
15 |
|
$subobject = new Subobject( $this->parserData->getTitle() ); |
263
|
15 |
|
$subobject->setEmptyContainerForId( '_SCITE' . md5( $reference ) ); |
264
|
|
|
|
265
|
15 |
|
$subject = $this->parserData->getSemanticData()->getSubject(); |
266
|
|
|
|
267
|
15 |
|
foreach ( $parserParameterProcessor->toArray() as $key => $values ) { |
268
|
|
|
|
269
|
15 |
|
if ( $key === DIProperty::TYPE_ERROR ) { |
270
|
|
|
|
271
|
1 |
|
$value = new DIProperty( end( $values ) ); |
272
|
|
|
|
273
|
1 |
|
$subobject->getSemanticData()->addPropertyObjectValue( |
274
|
1 |
|
new DIProperty( DIProperty::TYPE_ERROR ), |
275
|
1 |
|
$value->getDiWikiPage() |
276
|
|
|
); |
277
|
|
|
|
278
|
1 |
|
continue; |
279
|
|
|
} |
280
|
|
|
|
281
|
14 |
|
$property = $this->mediaWikiNsContentMapper->findPropertyForId( $key ); |
282
|
|
|
|
283
|
|
|
// No mapping, no annotation |
284
|
14 |
|
if ( $property === null ) { |
285
|
13 |
|
continue; |
286
|
|
|
} |
287
|
|
|
|
288
|
14 |
|
foreach ( $values as $value ) { |
289
|
|
|
|
290
|
14 |
|
$dataValue = $this->dataValueFactory->newPropertyValue( |
|
|
|
|
291
|
14 |
|
$property, |
292
|
14 |
|
trim( $value ), |
293
|
14 |
|
false, |
294
|
14 |
|
$subject |
295
|
|
|
); |
296
|
|
|
|
297
|
14 |
|
$subobject->addDataValue( $dataValue ); |
298
|
|
|
} |
299
|
|
|
} |
300
|
|
|
|
301
|
15 |
|
if ( $subobject->getSemanticData()->isEmpty() ) { |
302
|
|
|
return; |
303
|
|
|
} |
304
|
|
|
|
305
|
15 |
|
$this->parserData->getSemanticData()->addPropertyObjectValue( |
306
|
15 |
|
new DIProperty( PropertyRegistry::SCI_CITE ), |
307
|
15 |
|
$subobject->getContainer() |
308
|
|
|
); |
309
|
|
|
|
310
|
15 |
|
$this->parserData->getSubject()->setContextReference( 'scitep:' . uniqid() ); |
311
|
15 |
|
$this->parserData->pushSemanticDataToParserOutput(); |
|
|
|
|
312
|
15 |
|
} |
313
|
|
|
|
314
|
3 |
|
private function createErrorMessageFor( $messageKey, $arg1 = '', $arg2 = '' ) { |
315
|
3 |
|
return \Html::rawElement( |
316
|
3 |
|
'div', |
317
|
3 |
|
[ 'class' => 'smw-callout smw-callout-error' ], |
318
|
3 |
|
wfMessage( $messageKey, $arg1, $arg2 )->inContentLanguage()->text() |
319
|
|
|
); |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
} |
323
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.