You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

657 lines
35 KiB

  1. <?php
  2. // Project: Web Reference Database (refbase) <http://www.refbase.net>
  3. // Copyright: Matthias Steffens <mailto:refbase@extracts.de> and the file's
  4. // original author(s).
  5. //
  6. // This code is distributed in the hope that it will be useful,
  7. // but WITHOUT ANY WARRANTY. Please see the GNU General Public
  8. // License for more details.
  9. //
  10. // File: ./cite/styles/cite_Harvard_2.php
  11. // Repository: $HeadURL$
  12. // Author(s): Matthias Steffens <mailto:refbase@extracts.de>
  13. //
  14. // Created: 12-Aug-08, 20:00
  15. // Modified: $Date: 2012-02-27 20:25:30 +0000 (Mon, 27 Feb 2012) $
  16. // $Author$
  17. // $Revision: 1337 $
  18. // This is a citation style file (which must reside within the 'cite/styles/' sub-directory of your refbase root directory). It contains a
  19. // version of the 'citeRecord()' function that outputs a reference list from selected records according to the citation style used by
  20. // the Harvard referencing system
  21. // This is a variant of the Harvard author/date style, modeled after this guide:
  22. // <http://skillsforlearning.leedsmet.ac.uk/harvard_2004.pdf>
  23. // based on 'cite_Harvard_1.php'
  24. // NOTES: - For conference proceedings, you'll currently need to add the place & date of the conference in the proceedings title field
  25. // (e.g. "Proceedings of the 67th IFLA Council and General Conference, August 16-25, 2001, Boston USA").
  26. // TODO: - abstracts, conference proceedings, magazine articles, patents, reports & software?
  27. // - for references where there are more than four authors, we currently only use the first author followed by " et al"; is this correct?
  28. // - where to put (and how to format) series info & editors of whole books that also have an author?
  29. // - see also inline comments labeled with TODO (and NOTE)
  30. // --------------------------------------------------------------------
  31. // --- BEGIN CITATION STYLE ---
  32. function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
  33. {
  34. $record = ""; // make sure that our buffer variable is empty
  35. // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
  36. if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)$/", $row['type']))
  37. {
  38. if (!empty($row['author'])) // author
  39. {
  40. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  41. // 1. input: contents of the author field
  42. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  43. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  44. //
  45. // 3. input: pattern describing old delimiter that separates different authors
  46. // 4. output: for all authors except the last author: new delimiter that separates different authors
  47. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  48. //
  49. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  50. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  51. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  52. // 9. output: new delimiter that separates multiple initials (within one author)
  53. // 10. output: for the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  54. // 11. output: for all authors except the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  55. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  56. //
  57. // 13. output: if the total number of authors is greater than the given number (integer >= 1), only the number of authors given in (14) will be included in the citation along with the string given in (15); keep empty if all authors shall be returned
  58. // 14. output: number of authors (integer >= 1) that is included in the citation if the total number of authors is greater than the number given in (13); keep empty if not applicable
  59. // 15. output: string that's appended to the number of authors given in (14) if the total number of authors is greater than the number given in (13); the actual number of authors can be printed by including '__NUMBER_OF_AUTHORS__' (without quotes) within the string
  60. //
  61. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  62. $author = reArrangeAuthorContents($row['author'], // 1.
  63. true, // 2.
  64. "/ *; */", // 3.
  65. ", ", // 4.
  66. " " . $markupPatternsArray["ampersand"] . " ", // 5.
  67. "/ *, */", // 6.
  68. ", ", // 7.
  69. ", ", // 8.
  70. ".", // 9.
  71. false, // 10.
  72. false, // 11.
  73. true, // 12.
  74. "4", // 13.
  75. "1", // 14.
  76. " et al", // 15.
  77. $encodeHTML); // 16.
  78. $record .= $author;
  79. }
  80. if (!empty($row['year'])) // year
  81. $record .= " (" . $row['year'] . ")";
  82. if (!empty($row['title'])) // title
  83. $record .= " " . $row['title'] . ".";
  84. // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
  85. if (!empty($row['publication'])) // publication (= journal) name
  86. $record .= " " . $markupPatternsArray["italic-prefix"] . $row['publication'] . $markupPatternsArray["italic-suffix"];
  87. // if there's no full journal name, we'll use the abbreviated journal name instead:
  88. elseif (!empty($row['abbrev_journal'])) // abbreviated journal name
  89. $record .= " " . $markupPatternsArray["italic-prefix"] . $row['abbrev_journal'] . $markupPatternsArray["italic-suffix"];
  90. if ($row['online_publication'] == "yes") // this record refers to an online publication
  91. $record .= " [Internet]";
  92. if ((!empty($row['abbrev_journal']) || !empty($row['publication'])) && (!empty($row['volume']) || !empty($row['issue'])))
  93. $record .= ",";
  94. if ($row['type'] == "Journal Article")
  95. {
  96. if (!empty($row['volume'])) // volume
  97. $record .= " " . $row['volume'];
  98. if (!empty($row['issue'])) // issue
  99. {
  100. if (!empty($row['volume']))
  101. $record .= " ";
  102. $record .= "(" . $row['issue'] . ")";
  103. }
  104. }
  105. elseif (preg_match("/^(Newspaper Article|Magazine Article)$/", $row['type'])) // for newspaper and magazine articles, volume (=month) and issue (=day) information is printed without prefix
  106. {
  107. if (!empty($row['issue'])) // issue (=day)
  108. $record .= " " . $row['issue'];
  109. if (!empty($row['volume'])) // volume (=month)
  110. $record .= " " . $row['volume'];
  111. }
  112. if (!empty($row['pages'])) // pages
  113. {
  114. if (!empty($row['volume']) || !empty($row['issue']) || !empty($row['abbrev_journal']) || !empty($row['publication'])) // only add ", " if either volume, issue, abbrev_journal or publication isn't empty
  115. $record .= ", ";
  116. $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p.", "pp."); // function 'formatPageInfo()' is defined in 'cite.inc.php'
  117. }
  118. if ($row['online_publication'] == "yes") // this record refers to an online article
  119. {
  120. // append an optional string (given in 'online_citation') plus the current date and the DOI (or URL):
  121. if (!empty($row['online_citation'])) // online_citation
  122. {
  123. if (!empty($row['volume']) || !empty($row['issue']) || !empty($row['abbrev_journal']) || !empty($row['publication'])) // only add "," if either volume, issue, abbrev_journal or publication isn't empty
  124. $record .= ",";
  125. $record .= " " . $row['online_citation'];
  126. }
  127. if (!empty($row['doi']) || !empty($row['url'])) // doi OR url
  128. {
  129. if (!empty($row['online_citation']) OR (empty($row['online_citation']) AND (!empty($row['volume']) || !empty($row['issue']) || !empty($row['abbrev_journal']) || !empty($row['publication'])))) // only add "." if online_citation isn't empty, or else if either volume, issue, abbrev_journal or publication isn't empty
  130. $record .= ".";
  131. $today = date("j F Y");
  132. $record .= " Available from: ";
  133. if (!empty($row['doi'])) // doi
  134. $uri = "http://dx.doi.org/" . $row['doi'];
  135. else // url
  136. $uri = $row['url'];
  137. if ($encodeHTML)
  138. $record .= encodeHTML($markupPatternsArray["less-than"] . $uri . $markupPatternsArray["greater-than"]);
  139. else
  140. $record .= $markupPatternsArray["less-than"] . $uri . $markupPatternsArray["greater-than"];
  141. $record .= " [Accessed " . $today . "]";
  142. }
  143. }
  144. if (!preg_match("/\. *$/", $record)) // if the string doesn't end with a period
  145. $record .= ".";
  146. }
  147. // --- BEGIN TYPE = ABSTRACT / BOOK CHAPTER / CONFERENCE ARTICLE ------------------------------------------------------------------------
  148. elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)$/", $row['type']))
  149. {
  150. if (!empty($row['author'])) // author
  151. {
  152. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  153. // 1. input: contents of the author field
  154. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  155. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  156. //
  157. // 3. input: pattern describing old delimiter that separates different authors
  158. // 4. output: for all authors except the last author: new delimiter that separates different authors
  159. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  160. //
  161. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  162. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  163. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  164. // 9. output: new delimiter that separates multiple initials (within one author)
  165. // 10. output: for the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  166. // 11. output: for all authors except the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  167. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  168. //
  169. // 13. output: if the total number of authors is greater than the given number (integer >= 1), only the number of authors given in (14) will be included in the citation along with the string given in (15); keep empty if all authors shall be returned
  170. // 14. output: number of authors (integer >= 1) that is included in the citation if the total number of authors is greater than the number given in (13); keep empty if not applicable
  171. // 15. output: string that's appended to the number of authors given in (14) if the total number of authors is greater than the number given in (13); the actual number of authors can be printed by including '__NUMBER_OF_AUTHORS__' (without quotes) within the string
  172. //
  173. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  174. $author = reArrangeAuthorContents($row['author'], // 1.
  175. true, // 2.
  176. "/ *; */", // 3.
  177. ", ", // 4.
  178. " " . $markupPatternsArray["ampersand"] . " ", // 5.
  179. "/ *, */", // 6.
  180. ", ", // 7.
  181. ", ", // 8.
  182. ".", // 9.
  183. false, // 10.
  184. false, // 11.
  185. true, // 12.
  186. "4", // 13.
  187. "1", // 14.
  188. " et al", // 15.
  189. $encodeHTML); // 16.
  190. $record .= $author;
  191. }
  192. if (!empty($row['year'])) // year
  193. $record .= " (" . $row['year'] . ")";
  194. if (!empty($row['title'])) // title
  195. $record .= " " . $row['title'] . ".";
  196. // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
  197. // if this is not the case, the output string will begin with a space. However, any preceding/trailing whitespace will be removed at the cleanup stage (see below)
  198. if (!empty($row['editor'])) // editor
  199. {
  200. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  201. // 1. input: contents of the author field
  202. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  203. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  204. //
  205. // 3. input: pattern describing old delimiter that separates different authors
  206. // 4. output: for all authors except the last author: new delimiter that separates different authors
  207. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  208. //
  209. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  210. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  211. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  212. // 9. output: new delimiter that separates multiple initials (within one author)
  213. // 10. output: for the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  214. // 11. output: for all authors except the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  215. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  216. //
  217. // 13. output: if the total number of authors is greater than the given number (integer >= 1), only the number of authors given in (14) will be included in the citation along with the string given in (15); keep empty if all authors shall be returned
  218. // 14. output: number of authors (integer >= 1) that is included in the citation if the total number of authors is greater than the number given in (13); keep empty if not applicable
  219. // 15. output: string that's appended to the number of authors given in (14) if the total number of authors is greater than the number given in (13); the actual number of authors can be printed by including '__NUMBER_OF_AUTHORS__' (without quotes) within the string
  220. //
  221. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  222. $editor = reArrangeAuthorContents($row['editor'], // 1.
  223. true, // 2.
  224. "/ *; */", // 3.
  225. ", ", // 4.
  226. " " . $markupPatternsArray["ampersand"] . " ", // 5.
  227. "/ *, */", // 6.
  228. ", ", // 7.
  229. ", ", // 8.
  230. ".", // 9.
  231. false, // 10.
  232. false, // 11.
  233. true, // 12.
  234. "4", // 13.
  235. "1", // 14.
  236. " et al", // 15.
  237. $encodeHTML); // 16.
  238. $record .= " In: " . $editor . " ";
  239. if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+$/", $row['editor'])) // there are at least two editors (separated by ';')
  240. $record .= "eds.";
  241. else // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
  242. $record .= "ed.";
  243. }
  244. $publication = preg_replace("/[ \r\n]*\(Eds?:[^\)\r\n]*\)/i", "", $row['publication']);
  245. if (!empty($publication)) // publication
  246. {
  247. if (empty($row['editor']))
  248. $record .= " In:";
  249. $record .= " " . $markupPatternsArray["italic-prefix"] . $publication . $markupPatternsArray["italic-suffix"];
  250. }
  251. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition']) || !empty($row['volume']))
  252. {
  253. $record .= ". ";
  254. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition'])) // edition
  255. {
  256. if (preg_match("/^\d{1,3}$/", $row['edition'])) // if the edition field contains a number of up to three digits, we assume it's an edition number (such as "2nd ed.")
  257. {
  258. if ($row['edition'] == "2")
  259. $editionSuffix = "nd";
  260. elseif ($row['edition'] == "3")
  261. $editionSuffix = "rd";
  262. else
  263. $editionSuffix = "th";
  264. }
  265. else
  266. $editionSuffix = "";
  267. if (!empty($row['edition']) && !preg_match("/( ed\.?| edition)$/i", $row['edition']))
  268. $editionSuffix .= " ed.";
  269. $record .= $row['edition'] . $editionSuffix;
  270. }
  271. if (!empty($row['volume'])) // volume
  272. {
  273. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition']))
  274. $record .= ", ";
  275. $record .= "vol. " . $row['volume']; // TODO: not sure whether this is correct (should this be printed before the edition number?)
  276. }
  277. }
  278. if (!empty($row['abbrev_series_title']) OR !empty($row['series_title'])) // if there's either a full or an abbreviated series title
  279. {
  280. $record .= ". ";
  281. if (!empty($row['series_title']))
  282. $record .= $row['series_title']; // full series title
  283. // if there's no full series title, we'll use the abbreviated series title instead:
  284. elseif (!empty($row['abbrev_series_title']))
  285. $record .= $row['abbrev_series_title']; // abbreviated series title
  286. if (!empty($row['series_volume'])||!empty($row['series_issue']))
  287. $record .= ", ";
  288. if (!empty($row['series_volume'])) // series volume (I'm not really sure if -- for this cite style -- the series volume & issue should be rather omitted here)
  289. $record .= "vol. " . $row['series_volume']; // TODO: not sure whether this is correct
  290. if (!empty($row['series_issue'])) // series issue (see note for series volume)
  291. {
  292. if (!empty($row['series_volume']))
  293. $record .= ", ";
  294. $record .= "no. " . $row['series_issue']; // TODO: not sure whether this is correct
  295. }
  296. }
  297. if (!preg_match("/\. *$/", $record))
  298. $record .= ".";
  299. if (!empty($row['place'])) // place
  300. $record .= " " . $row['place'];
  301. if (!empty($row['publisher'])) // publisher
  302. {
  303. if (!empty($row['place']))
  304. $record .= ",";
  305. $record .= " " . $row['publisher'];
  306. }
  307. if (!empty($row['pages'])) // pages
  308. {
  309. if (!empty($row['publisher']) || !empty($row['place']))
  310. $record .= ", ";
  311. $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p.", "pp."); // function 'formatPageInfo()' is defined in 'cite.inc.php'
  312. }
  313. if (!preg_match("/\. *$/", $record))
  314. $record .= ".";
  315. }
  316. // --- BEGIN TYPE = BOOK WHOLE / CONFERENCE VOLUME / JOURNAL / MANUAL / MANUSCRIPT / MAP / MISCELLANEOUS / PATENT / REPORT / SOFTWARE ---
  317. else // if (preg_match("/Book Whole|Conference Volume|Journal|Manual|Manuscript|Map|Miscellaneous|Patent|Report|Software/", $row['type']))
  318. // note that this also serves as a fallback: unrecognized resource types will be formatted similar to whole books
  319. {
  320. if (!empty($row['author'])) // author
  321. {
  322. $author = preg_replace("/[ \r\n]*\(eds?\)/i", "", $row['author']);
  323. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  324. // 1. input: contents of the author field
  325. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  326. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  327. //
  328. // 3. input: pattern describing old delimiter that separates different authors
  329. // 4. output: for all authors except the last author: new delimiter that separates different authors
  330. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  331. //
  332. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  333. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  334. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  335. // 9. output: new delimiter that separates multiple initials (within one author)
  336. // 10. output: for the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  337. // 11. output: for all authors except the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  338. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  339. //
  340. // 13. output: if the total number of authors is greater than the given number (integer >= 1), only the number of authors given in (14) will be included in the citation along with the string given in (15); keep empty if all authors shall be returned
  341. // 14. output: number of authors (integer >= 1) that is included in the citation if the total number of authors is greater than the number given in (13); keep empty if not applicable
  342. // 15. output: string that's appended to the number of authors given in (14) if the total number of authors is greater than the number given in (13); the actual number of authors can be printed by including '__NUMBER_OF_AUTHORS__' (without quotes) within the string
  343. //
  344. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  345. $author = reArrangeAuthorContents($author, // 1.
  346. true, // 2.
  347. "/ *; */", // 3.
  348. ", ", // 4.
  349. " " . $markupPatternsArray["ampersand"] . " ", // 5.
  350. "/ *, */", // 6.
  351. ", ", // 7.
  352. ", ", // 8.
  353. ".", // 9.
  354. false, // 10.
  355. false, // 11.
  356. true, // 12.
  357. "4", // 13.
  358. "1", // 14.
  359. " et al", // 15.
  360. $encodeHTML); // 16.
  361. // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
  362. // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
  363. // so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
  364. if (preg_match("/[ \r\n]*\(ed\)/", $row['author'])) // single editor
  365. $author = $author . " ed.";
  366. elseif (preg_match("/[ \r\n]*\(eds\)/", $row['author'])) // multiple editors
  367. $author = $author . " eds.";
  368. $record .= $author;
  369. }
  370. if (!empty($row['year'])) // year
  371. $record .= " (" . $row['year'] . ")";
  372. if (!empty($row['title'])) // title
  373. $record .= " " . $markupPatternsArray["italic-prefix"] . $row['title'] . $markupPatternsArray["italic-suffix"];
  374. if ($row['online_publication'] == "yes") // this record refers to an online publication
  375. $record .= " [Internet]";
  376. if (!empty($row['editor']) && !preg_match("/[ \r\n]*\(eds?\)/", $row['author'])) // editor (if different from author, see note above regarding the check for ' (ed)' or ' (eds)')
  377. {
  378. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  379. // 1. input: contents of the author field
  380. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  381. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  382. //
  383. // 3. input: pattern describing old delimiter that separates different authors
  384. // 4. output: for all authors except the last author: new delimiter that separates different authors
  385. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  386. //
  387. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  388. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  389. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  390. // 9. output: new delimiter that separates multiple initials (within one author)
  391. // 10. output: for the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  392. // 11. output: for all authors except the first author: boolean value that specifies if initials go *before* the author's name ['true'], or *after* the author's name ['false'] (which is the default in the db)
  393. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  394. //
  395. // 13. output: if the total number of authors is greater than the given number (integer >= 1), only the number of authors given in (14) will be included in the citation along with the string given in (15); keep empty if all authors shall be returned
  396. // 14. output: number of authors (integer >= 1) that is included in the citation if the total number of authors is greater than the number given in (13); keep empty if not applicable
  397. // 15. output: string that's appended to the number of authors given in (14) if the total number of authors is greater than the number given in (13); the actual number of authors can be printed by including '__NUMBER_OF_AUTHORS__' (without quotes) within the string
  398. //
  399. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  400. $editor = reArrangeAuthorContents($row['editor'], // 1.
  401. true, // 2.
  402. "/ *; */", // 3.
  403. ", ", // 4.
  404. " " . $markupPatternsArray["ampersand"] . " ", // 5.
  405. "/ *, */", // 6.
  406. ", ", // 7.
  407. ", ", // 8.
  408. ".", // 9.
  409. false, // 10.
  410. false, // 11.
  411. true, // 12.
  412. "4", // 13.
  413. "1", // 14.
  414. " et al", // 15.
  415. $encodeHTML); // 16.
  416. if (!empty($row['author']) || !empty($row['year']) || !empty($row['title']))
  417. $record .= " ";
  418. $record .= " (" . $editor . " ";
  419. if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+$/", $row['editor'])) // there are at least two editors (separated by ';')
  420. $record .= "eds.";
  421. else // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
  422. $record .= "ed.";
  423. $record .= ")";
  424. }
  425. if (!empty($row['edition']) || !empty($row['volume']))
  426. {
  427. if (!empty($row['author']) || !empty($row['year']) || !empty($row['title']) || (!empty($row['editor']) && !preg_match("/[ \r\n]*\(eds?\)/", $row['author'])))
  428. $record .= ". ";
  429. if ($row['type'] == "Software") // software edition (=version)
  430. {
  431. if (!empty($row['edition']))
  432. {
  433. $record .= "Version " . $row['edition'];
  434. if (!empty($row['volume']) || !empty($row['issue']))
  435. $record .= ", ";
  436. }
  437. if (!empty($row['issue'])) // issue (=day)
  438. $record .= " " . $row['issue'];
  439. if (!empty($row['volume'])) // volume (=month)
  440. $record .= " " . $row['volume'];
  441. }
  442. elseif (!preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition'])) // regular edition (other than the first)
  443. {
  444. if (preg_match("/^\d{1,3}$/", $row['edition'])) // if the edition field contains a number of up to three digits, we assume it's an edition number (such as "2nd ed.")
  445. {
  446. if ($row['edition'] == "2")
  447. $editionSuffix = "nd";
  448. elseif ($row['edition'] == "3")
  449. $editionSuffix = "rd";
  450. else
  451. $editionSuffix = "th";
  452. }
  453. else
  454. $editionSuffix = "";
  455. if (!empty($row['edition']) && !preg_match("/( ed\.?| edition)$/i", $row['edition']))
  456. $editionSuffix .= " ed.";
  457. $record .= $row['edition'] . $editionSuffix;
  458. if (!empty($row['volume'])) // volume
  459. {
  460. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition']))
  461. $record .= ", ";
  462. $record .= "vol. " . $row['volume']; // TODO: not sure whether this is correct (should this be printed before the edition number?)
  463. }
  464. }
  465. }
  466. if ($row['type'] == "Software") // for software, add software label
  467. {
  468. $record .= ", computer software.";
  469. }
  470. else // add series info
  471. {
  472. if (!preg_match("/\. *$/", $record))
  473. $record .= ".";
  474. if (!empty($row['abbrev_series_title']) OR !empty($row['series_title'])) // if there's either a full or an abbreviated series title
  475. {
  476. $record .= " ";
  477. if (!empty($row['series_title']))
  478. $record .= $row['series_title']; // full series title
  479. // if there's no full series title, we'll use the abbreviated series title instead:
  480. elseif (!empty($row['abbrev_series_title']))
  481. $record .= $row['abbrev_series_title']; // abbreviated series title
  482. if (!empty($row['series_volume'])||!empty($row['series_issue']))
  483. $record .= ", ";
  484. if (!empty($row['series_volume'])) // series volume (I'm not really sure if -- for this cite style -- the series volume & issue should be rather omitted here)
  485. $record .= "vol. " . $row['series_volume']; // TODO: not sure whether this is correct
  486. if (!empty($row['series_issue'])) // series issue (see note for series volume)
  487. {
  488. if (!empty($row['series_volume']))
  489. $record .= ", ";
  490. $record .= "no. " . $row['series_issue']; // TODO: not sure whether this is correct
  491. }
  492. $record .= ".";
  493. }
  494. }
  495. if (!empty($row['thesis'])) // thesis
  496. $record .= " " . $row['thesis'];
  497. if (!empty($row['place']) || !empty($row['publisher']))
  498. {
  499. if (!empty($row['thesis']))
  500. $record .= ",";
  501. if (!empty($row['place'])) // place (NOTE: should we omit the place of publication for theses?)
  502. $record .= " " . $row['place'];
  503. if (!empty($row['publisher'])) // publisher
  504. {
  505. if (!empty($row['place']))
  506. $record .= ",";
  507. $record .= " " . $row['publisher'];
  508. }
  509. }
  510. if ($row['online_publication'] == "yes" || $row['type'] == "Software") // this record refers to an online article, or a computer program/software
  511. {
  512. if (!empty($row['online_citation'])) // online_citation
  513. {
  514. if (!preg_match("/\. *$/", $record))
  515. $record .= ".";
  516. $record .= " " . $row['online_citation'];
  517. }
  518. if (!empty($row['doi']) || !empty($row['url'])) // doi OR url
  519. {
  520. if (!preg_match("/\. *$/", $record))
  521. $record .= ".";
  522. $today = date("j F Y");
  523. $record .= " Available from: ";
  524. if (!empty($row['doi'])) // doi
  525. $uri = "http://dx.doi.org/" . $row['doi'];
  526. else // url
  527. $uri = $row['url'];
  528. if ($encodeHTML)
  529. $record .= encodeHTML($markupPatternsArray["less-than"] . $uri . $markupPatternsArray["greater-than"]);
  530. else
  531. $record .= $markupPatternsArray["less-than"] . $uri . $markupPatternsArray["greater-than"];
  532. $record .= " [Accessed " . $today . "]";
  533. }
  534. }
  535. if (!preg_match("/\. *$/", $record)) // if the string doesn't end with a period
  536. $record .= ".";
  537. }
  538. // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
  539. // do some further cleanup:
  540. $record = trim($record); // remove any preceding or trailing whitespace
  541. return $record;
  542. }
  543. // --- END CITATION STYLE ---
  544. ?>