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.

660 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_MLA.php
  11. // Repository: $HeadURL: file:///svn/p/refbase/code/branches/bleeding-edge/cite/styles/cite_MLA.php $
  12. // Author(s): Richard Karnesky <mailto:karnesky@gmail.com> and
  13. // Matthias Steffens <mailto:refbase@extracts.de>
  14. //
  15. // Created: 13-Nov-06, 15: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 Modern Language Association (MLA)
  22. // based on 'cite_APA.php'
  23. // TODO: - newspaper & magazine articles, conference proceedings, manuals, patents, reports, software, published dissertation
  24. // - use dashes for subsequent entries when citing two or more books by the same author -> see e.g. example at: <http://web.csustan.edu/english/reuben/pal/append/AXI.HTML>
  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. ", and ", // 5.
  63. "/ *, */", // 6.
  64. ", ", // 7.
  65. " ", // 8.
  66. ". ", // 9.
  67. false, // 10.
  68. true, // 11.
  69. false, // 12.
  70. "3", // 13.
  71. "1", // 14.
  72. ", et al.", // 15.
  73. $encodeHTML); // 16.
  74. if (!preg_match("/\. *$/", $author))
  75. $record .= $author . ".";
  76. else
  77. $record .= $author;
  78. }
  79. if (!empty($row['title'])) // title
  80. {
  81. if (!empty($row['author']))
  82. $record .= " ";
  83. $record .= '"' . $row['title'];
  84. if (!preg_match("/[?!.]$/", $row['title']))
  85. $record .= ".";
  86. $record .= '"';
  87. }
  88. // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
  89. // 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)
  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 (!empty($row['volume'])) // volume
  96. {
  97. if (!empty($row['abbrev_journal']) || !empty($row['publication']))
  98. $record .= ".";
  99. $record .= " " . $row['volume'];
  100. }
  101. if (!empty($row['issue'])) // issue
  102. $record .= "." . $row['issue'];
  103. if (!empty($row['year'])) // year
  104. {
  105. $record .= " (".$row['year'] . ")";
  106. }
  107. if ($row['online_publication'] == "yes") // this record refers to an online article
  108. {
  109. // instead of any pages info (which normally doesn't exist for online publications) we append
  110. // an optional string (given in 'online_citation') plus the current date and the DOI (or URL):
  111. $today = date("j M. Y");
  112. if (!empty($row['online_citation'])) // online_citation
  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 .= " " . $row['online_citation'];
  117. }
  118. if (!empty($row['doi'])) // doi
  119. {
  120. 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
  121. $record .= ".";
  122. if ($encodeHTML)
  123. $record .= " " . $today . encodeHTML(" <http://dx.doi.org/" . $row['doi'] . ">");
  124. else
  125. $record .= " " . $today . " <http://dx.doi.org/" . $row['doi'] . ">";
  126. }
  127. elseif (!empty($row['url'])) // 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. if ($encodeHTML)
  132. $record .= " " . $today . encodeHTML(" <" . $row['url'] . ">");
  133. else
  134. $record .= " " . $today . " <" . $row['url'] . ">";
  135. }
  136. }
  137. else // $row['online_publication'] == "no" -> this record refers to a printed article, so we append any pages info instead:
  138. {
  139. if (!empty($row['pages'])) // pages
  140. {
  141. if (!empty($row['year']) || !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
  142. $record .= ": ";
  143. $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"]); // function 'formatPageInfo()' is defined in 'cite.inc.php'
  144. }
  145. }
  146. if (!preg_match("/\. *$/", $record))
  147. $record .= ".";
  148. }
  149. // --- BEGIN TYPE = ABSTRACT / BOOK CHAPTER / CONFERENCE ARTICLE ------------------------------------------------------------------------
  150. elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)$/", $row['type']))
  151. {
  152. if (!empty($row['author'])) // author
  153. {
  154. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  155. // 1. input: contents of the author field
  156. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  157. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  158. //
  159. // 3. input: pattern describing old delimiter that separates different authors
  160. // 4. output: for all authors except the last author: new delimiter that separates different authors
  161. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  162. //
  163. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  164. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  165. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  166. // 9. output: new delimiter that separates multiple initials (within one author)
  167. // 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)
  168. // 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)
  169. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  170. //
  171. // 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
  172. // 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
  173. // 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
  174. //
  175. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  176. $author = reArrangeAuthorContents($row['author'], // 1.
  177. true, // 2.
  178. "/ *; */", // 3.
  179. ", ", // 4.
  180. ", and ", // 5.
  181. "/ *, */", // 6.
  182. ", ", // 7.
  183. " ", // 8.
  184. ". ", // 9.
  185. false, // 10.
  186. true, // 11.
  187. false, // 12.
  188. "3", // 13.
  189. "1", // 14.
  190. ", et al.", // 15.
  191. $encodeHTML); // 16.
  192. if (!preg_match("/\. *$/", $author))
  193. $record .= $author . ".";
  194. else
  195. $record .= $author;
  196. }
  197. if (!empty($row['title'])) // title
  198. {
  199. if (!empty($row['author']))
  200. $record .= " ";
  201. $record .= '"' . $row['title'];
  202. if (!preg_match("/[?!.]$/", $row['title']))
  203. $record .= ".";
  204. $record .= '"';
  205. }
  206. $publication = preg_replace("/[ \r\n]*\(Eds?:[^\)\r\n]*\)/i", "", $row['publication']);
  207. if (!empty($publication)) // publication
  208. $record .= " " . $markupPatternsArray["italic-prefix"] . $publication . $markupPatternsArray["italic-suffix"];
  209. // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
  210. // 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)
  211. if (!empty($row['editor'])) // editor
  212. {
  213. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  214. // 1. input: contents of the author field
  215. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  216. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  217. //
  218. // 3. input: pattern describing old delimiter that separates different authors
  219. // 4. output: for all authors except the last author: new delimiter that separates different authors
  220. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  221. //
  222. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  223. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  224. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  225. // 9. output: new delimiter that separates multiple initials (within one author)
  226. // 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)
  227. // 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)
  228. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  229. //
  230. // 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
  231. // 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
  232. // 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
  233. //
  234. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  235. $editor = reArrangeAuthorContents($row['editor'], // 1.
  236. true, // 2.
  237. "/ *; */", // 3.
  238. ", ", // 4.
  239. ", and ", // 5.
  240. "/ *, */", // 6.
  241. " ", // 7.
  242. " ", // 8.
  243. ". ", // 9.
  244. true, // 10.
  245. true, // 11.
  246. false, // 12.
  247. "3", // 13.
  248. "1", // 14.
  249. ", et al.", // 15.
  250. $encodeHTML); // 16.
  251. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  252. $record .= ".";
  253. if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+$/", $row['editor'])) // there are at least two editors (separated by ';')
  254. $record .= " Eds. " . $editor;
  255. else // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
  256. $record .= " Ed. " . $editor;
  257. }
  258. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition'])) // edition
  259. {
  260. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  261. $record .= ".";
  262. 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.")
  263. {
  264. if ($row['edition'] == "2")
  265. $editionSuffix = "nd";
  266. elseif ($row['edition'] == "3")
  267. $editionSuffix = "rd";
  268. else
  269. $editionSuffix = "th";
  270. }
  271. else
  272. $editionSuffix = "";
  273. if (preg_match("/^(Rev\.?|Revised)( ed\.?| edition)?$/i", $row['edition']))
  274. $row['edition'] = "Rev.";
  275. elseif (preg_match("/^(Abr\.?|Abridged)( ed\.?| edition)?$/i", $row['edition']))
  276. $row['edition'] = "Abr.";
  277. if (!preg_match("/( ed\.?| edition)$/i", $row['edition']))
  278. $editionSuffix .= " ed.";
  279. $record .= " " . $row['edition'] . $editionSuffix;
  280. }
  281. if (!empty($row['volume'])) // volume
  282. {
  283. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  284. $record .= ".";
  285. $record .= " Vol. " . $row['volume'];
  286. }
  287. if (!empty($row['abbrev_series_title']) OR !empty($row['series_title'])) // if there's either a full or an abbreviated series title
  288. {
  289. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  290. $record .= ".";
  291. $record .= " ";
  292. if (!empty($row['abbrev_series_title']))
  293. $record .= $row['abbrev_series_title']; // abbreviated series title
  294. // if there's no abbreviated series title, we'll use the full series title instead:
  295. elseif (!empty($row['series_title']))
  296. $record .= $row['series_title']; // full series title
  297. if (!empty($row['series_volume'])||!empty($row['series_issue']))
  298. $record .= ", ";
  299. if (!empty($row['series_volume'])) // series volume
  300. $record .= $row['series_volume'];
  301. 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)
  302. $record .= "." . $row['series_issue']; // is it correct to format series issues similar to journal article issues?
  303. }
  304. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  305. $record .= ".";
  306. if (!empty($row['place'])) // place
  307. $record .= " " . $row['place'];
  308. if (!empty($row['publisher'])) // publisher
  309. {
  310. if (!empty($row['place']))
  311. $record .= ":";
  312. $record .= " " . $row['publisher'];
  313. }
  314. if (!empty($row['year'])) // year
  315. {
  316. $record .= ", " . $row['year'];
  317. }
  318. if (!empty($row['pages'])) // pages
  319. $record .= ". " . formatPageInfo($row['pages'], $markupPatternsArray["endash"]); // function 'formatPageInfo()' is defined in 'cite.inc.php'
  320. if (!preg_match("/\. *$/", $record))
  321. $record .= ".";
  322. }
  323. // --- BEGIN TYPE = BOOK WHOLE / CONFERENCE VOLUME / JOURNAL / MANUAL / MANUSCRIPT / MAP / MISCELLANEOUS / PATENT / REPORT / SOFTWARE ---
  324. else // if (preg_match("/Book Whole|Conference Volume|Journal|Manual|Manuscript|Map|Miscellaneous|Patent|Report|Software/", $row['type']))
  325. // note that this also serves as a fallback: unrecognized resource types will be formatted similar to whole books
  326. {
  327. if (!empty($row['author'])) // author
  328. {
  329. $author = preg_replace("/[ \r\n]*\(eds?\)/i", "", $row['author']);
  330. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  331. // 1. input: contents of the author field
  332. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  333. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  334. //
  335. // 3. input: pattern describing old delimiter that separates different authors
  336. // 4. output: for all authors except the last author: new delimiter that separates different authors
  337. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  338. //
  339. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  340. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  341. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  342. // 9. output: new delimiter that separates multiple initials (within one author)
  343. // 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)
  344. // 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)
  345. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  346. //
  347. // 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
  348. // 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
  349. // 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
  350. //
  351. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  352. $author = reArrangeAuthorContents($author, // 1.
  353. true, // 2.
  354. "/ *; */", // 3.
  355. ", ", // 4.
  356. ", and ", // 5.
  357. "/ *, */", // 6.
  358. ", ", // 7.
  359. " ", // 8.
  360. ". ", // 9.
  361. false, // 10.
  362. true, // 11.
  363. false, // 12.
  364. "3", // 13.
  365. "1", // 14.
  366. ", et al.", // 15.
  367. $encodeHTML); // 16.
  368. // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
  369. // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
  370. // so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
  371. if (preg_match("/[ \r\n]*\(ed\)/", $row['author'])) // single editor
  372. $author = $author . ", " . "ed";
  373. elseif (preg_match("/[ \r\n]*\(eds\)/", $row['author'])) // multiple editors
  374. $author = $author . ", " . "eds";
  375. if (!preg_match("/\. *$/", $author))
  376. $record .= $author . ".";
  377. else
  378. $record .= $author;
  379. }
  380. if (!empty($row['title'])) // title
  381. {
  382. if (!empty($row['author']))
  383. $record .= " ";
  384. if (!empty($row['thesis'])) // thesis
  385. {
  386. $record .= '"' . $row['title'];
  387. if (!preg_match("/[?!.]$/", $row['title']))
  388. $record .= ".";
  389. $record .= '"';
  390. }
  391. else // not a thesis
  392. $record .= $markupPatternsArray["italic-prefix"] . $row['title'] . $markupPatternsArray["italic-suffix"];
  393. }
  394. 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)')
  395. {
  396. // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
  397. // 1. input: contents of the author field
  398. // 2. input: boolean value that specifies whether the author's family name comes first (within one author) in the source string
  399. // ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
  400. //
  401. // 3. input: pattern describing old delimiter that separates different authors
  402. // 4. output: for all authors except the last author: new delimiter that separates different authors
  403. // 5. output: for the last author: new delimiter that separates the last author from all other authors
  404. //
  405. // 6. input: pattern describing old delimiter that separates author name & initials (within one author)
  406. // 7. output: for the first author: new delimiter that separates author name & initials (within one author)
  407. // 8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
  408. // 9. output: new delimiter that separates multiple initials (within one author)
  409. // 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)
  410. // 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)
  411. // 12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
  412. //
  413. // 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
  414. // 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
  415. // 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
  416. //
  417. // 16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
  418. $editor = reArrangeAuthorContents($row['editor'], // 1.
  419. true, // 2.
  420. "/ *; */", // 3.
  421. ", ", // 4.
  422. ", and ", // 5.
  423. "/ *, */", // 6.
  424. " ", // 7.
  425. " ", // 8.
  426. ". ", // 9.
  427. true, // 10.
  428. true, // 11.
  429. false, // 12.
  430. "3", // 13.
  431. "1", // 14.
  432. ", et al.", // 15.
  433. $encodeHTML); // 16.
  434. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  435. $record .= ".";
  436. if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+$/", $row['editor'])) // there are at least two editors (separated by ';')
  437. $record .= " Eds. " . $editor;
  438. else // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
  439. $record .= " Ed. " . $editor;
  440. }
  441. if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\.?| edition)?$/i", $row['edition'])) // edition
  442. {
  443. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  444. $record .= ".";
  445. 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.")
  446. {
  447. if ($row['edition'] == "2")
  448. $editionSuffix = "nd";
  449. elseif ($row['edition'] == "3")
  450. $editionSuffix = "rd";
  451. else
  452. $editionSuffix = "th";
  453. }
  454. else
  455. $editionSuffix = "";
  456. if (preg_match("/^(Rev\.?|Revised)( ed\.?| edition)?$/i", $row['edition']))
  457. $row['edition'] = "Rev.";
  458. elseif (preg_match("/^(Abr\.?|Abridged)( ed\.?| edition)?$/i", $row['edition']))
  459. $row['edition'] = "Abr.";
  460. if (!preg_match("/( ed\.?| edition)$/i", $row['edition']))
  461. $editionSuffix .= " ed.";
  462. $record .= " " . $row['edition'] . $editionSuffix;
  463. }
  464. if (!empty($row['volume'])) // volume
  465. {
  466. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  467. $record .= ".";
  468. $record .= " Vol. " . $row['volume'];
  469. }
  470. if (!empty($row['abbrev_series_title']) OR !empty($row['series_title'])) // if there's either a full or an abbreviated series title
  471. {
  472. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  473. $record .= ".";
  474. $record .= " ";
  475. if (!empty($row['abbrev_series_title']))
  476. $record .= $row['abbrev_series_title']; // abbreviated series title
  477. // if there's no abbreviated series title, we'll use the full series title instead:
  478. elseif (!empty($row['series_title']))
  479. $record .= $row['series_title']; // full series title
  480. if (!empty($row['series_volume'])||!empty($row['series_issue']))
  481. $record .= ", ";
  482. if (!empty($row['series_volume'])) // series volume
  483. $record .= $row['series_volume'];
  484. 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)
  485. $record .= "." . $row['series_issue']; // is it correct to format series issues similar to journal article issues?
  486. }
  487. if (!empty($row['thesis'])) // thesis (unpublished dissertation)
  488. {
  489. // TODO: a published dissertation needs to be formatted differently!
  490. // see e.g. example at: <http://web.csustan.edu/english/reuben/pal/append/AXI.HTML>
  491. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  492. $record .= ".";
  493. // TODO: I've also seen MLA examples that separate thesis name, name of institution and year by dots. ?:-|
  494. // Also, do we need to use the abbreviation "Diss." instead of "Ph.D. thesis"? What about other thesis types then?
  495. // see e.g. <http://www.english.uiuc.edu/cws/wworkshop/writer_resources/citation_styles/mla/unpublished_diss.htm>
  496. $record .= " " . $row['thesis'];
  497. $record .= ", " . $row['publisher'];
  498. }
  499. else // not a thesis
  500. {
  501. if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*$@", $record))
  502. $record .= ".";
  503. if (!empty($row['place'])) // place
  504. $record .= " " . $row['place'];
  505. if (!empty($row['publisher'])) // publisher
  506. {
  507. if (!empty($row['place']))
  508. $record .= ":";
  509. $record .= " " . $row['publisher'];
  510. }
  511. }
  512. if (!empty($row['year'])) // year
  513. $record .= ", ".$row['year'];
  514. if ($row['online_publication'] == "yes") // this record refers to an online article
  515. {
  516. $today = date("j M. Y");
  517. if (!empty($row['online_citation'])) // online_citation
  518. {
  519. if (!preg_match("/\. *$/", $record))
  520. $record .= ".";
  521. $record .= " " . $row['online_citation'];
  522. }
  523. if (!empty($row['doi'])) // doi
  524. {
  525. if (!preg_match("/\. *$/", $record))
  526. $record .= ".";
  527. if ($encodeHTML)
  528. $record .= " " . $today . encodeHTML(" <http://dx.doi.org/" . $row['doi'] . ">");
  529. else
  530. $record .= " " . $today . " <http://dx.doi.org/" . $row['doi'] . ">";
  531. }
  532. elseif (!empty($row['url'])) // url
  533. {
  534. if (!preg_match("/\. *$/", $record))
  535. $record .= ".";
  536. if ($encodeHTML)
  537. $record .= " " . $today . encodeHTML(" <" . $row['url'] . ">");
  538. else
  539. $record .= " " . $today . " <" . $row['url'] . ">";
  540. }
  541. }
  542. if (!preg_match("/\. *$/", $record))
  543. $record .= ".";
  544. }
  545. // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
  546. // do some further cleanup:
  547. $record = trim($record); // remove any preceding or trailing whitespace
  548. return $record;
  549. }
  550. // --- END CITATION STYLE ---
  551. ?>