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.

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