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.

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