function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
{
    $record = "";
    // make sure that our buffer variable is empty
    // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
    if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", " and ", "/ *, */", ", ", " ", ".", false, true, true, "6", "1", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['year'] . ".";
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= " ";
            }
            $record .= $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
        }
        // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
        // 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)
        if (!empty($row['abbrev_journal'])) {
            // abbreviated journal name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['abbrev_journal'] . $markupPatternsArray["italic-suffix"];
        } elseif (!empty($row['publication'])) {
            // publication (= journal) name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['publication'] . $markupPatternsArray["italic-suffix"];
        }
        if (!empty($row['volume'])) {
            if (!empty($row['abbrev_journal']) || !empty($row['publication'])) {
                $record .= ",";
            }
            $record .= " " . $markupPatternsArray["bold-prefix"] . $row['volume'] . $markupPatternsArray["bold-suffix"];
        }
        if (!empty($row['issue'])) {
            // issue
            $record .= "(" . $row['issue'] . ")";
        }
        if ($row['online_publication'] == "yes") {
            // instead of any pages info (which normally doesn't exist for online publications) we append
            // an optional string (given in 'online_citation') plus the DOI:
            if (!empty($row['online_citation'])) {
                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
                    $record .= ",";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi'])) {
                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
                    $record .= ".";
                }
                $record .= " (" . $row['doi'] . ".)";
            }
        } else {
            if (!empty($row['pages'])) {
                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
                    $record .= ", ";
                }
                $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"]);
                // function 'formatPageInfo()' is defined in 'cite.inc.php'
            }
        }
        if (!preg_match("/\\.\\)? *\$/", $record)) {
            $record .= ".";
        }
    } elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", " and ", "/ *, */", ", ", " ", ".", false, true, true, "6", "1", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['year'] . ".";
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= " ";
            }
            $record .= $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
        }
        // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
        // 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)
        if (!empty($row['editor'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", " and ", "/ *, */", ", ", " ", ".", false, true, true, "6", "1", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            $record .= " " . $markupPatternsArray["italic-prefix"] . "In" . $markupPatternsArray["italic-suffix"] . " " . $editor;
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= ", " . $markupPatternsArray["italic-prefix"] . "eds" . $markupPatternsArray["italic-suffix"] . ".";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= ", " . $markupPatternsArray["italic-prefix"] . "ed" . $markupPatternsArray["italic-suffix"] . ".";
            }
        }
        $publication = preg_replace("/[ \r\n]*\\(Eds?:[^\\)\r\n]*\\)/i", "", $row['publication']);
        if (!empty($publication)) {
            // publication
            $record .= " " . $markupPatternsArray["italic-prefix"] . $publication . $markupPatternsArray["italic-suffix"] . ".";
        }
        if (!empty($row['place'])) {
            // place
            $record .= " " . $row['place'];
        }
        if (!empty($row['publisher'])) {
            if (!empty($row['place'])) {
                $record .= ",";
            }
            $record .= " " . $row['publisher'];
        }
        if (!empty($row['pages'])) {
            if (!empty($row['place']) || !empty($row['publisher'])) {
                $record .= ", ";
            }
            $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"]);
            // function 'formatPageInfo()' is defined in 'cite.inc.php'
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            $record .= " (";
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= " ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            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)
                $record .= "(" . $row['series_issue'] . ")";
            }
            $record .= ".)";
        }
    } else {
        if (!empty($row['author'])) {
            $author = preg_replace("/[ \r\n]*\\(eds?\\)/i", "", $row['author']);
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($author, true, "/ *; */", ", ", " and ", "/ *, */", ", ", " ", ".", false, true, true, "6", "1", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
            // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
            //  so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
            if (preg_match("/[ \r\n]*\\(ed\\)/", $row['author'])) {
                // single editor
                $author = $author . ", " . $markupPatternsArray["italic-prefix"] . "ed" . $markupPatternsArray["italic-suffix"];
            } elseif (preg_match("/[ \r\n]*\\(eds\\)/", $row['author'])) {
                // multiple editors
                $author = $author . ", " . $markupPatternsArray["italic-prefix"] . "eds" . $markupPatternsArray["italic-suffix"];
            }
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['year'] . ".";
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= " ";
            }
            $record .= $markupPatternsArray["italic-prefix"] . $row['title'] . $markupPatternsArray["italic-suffix"];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
        }
        if (!empty($row['thesis'])) {
            $record .= " (" . $row['thesis'];
            $record .= ", " . $row['publisher'] . ".)";
        } else {
            if (!empty($row['place'])) {
                // place
                $record .= " " . $row['place'];
            }
            if (!empty($row['publisher'])) {
                if (!empty($row['place'])) {
                    $record .= ",";
                }
                $record .= " " . $row['publisher'];
            }
            //						if (!empty($row['pages']))      // pages
            //						{
            //							if (!empty($row['place']) || !empty($row['publisher']))
            //								$record .= ", ";
            //
            //							$record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"]); // function 'formatPageInfo()' is defined in 'cite.inc.php'
            //						}
            if (!preg_match("/\\. *\$/", $record)) {
                $record .= ".";
            }
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            $record .= " (";
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= " ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            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)
                $record .= "(" . $row['series_issue'] . ")";
            }
            $record .= ".)";
        }
    }
    // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
    // do some further cleanup:
    $record = trim($record);
    // remove any preceding or trailing whitespace
    return $record;
}
function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
{
    $record = "";
    // make sure that our buffer variable is empty
    // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
    if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", " " . $markupPatternsArray["ampersand"] . " ", "/ *, */", ", ", ", ", ".", false, false, true, "4", "1", " et al", $encodeHTML);
            // 16.
            $record .= $author;
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= ", ";
            }
            if (!empty($row['year'])) {
                $record .= $row['year'];
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= ". ";
            }
            $record .= $row['title'];
            $record .= ",";
        }
        // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
        if (!empty($row['publication'])) {
            // publication (= journal) name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['publication'] . $markupPatternsArray["italic-suffix"];
        } elseif (!empty($row['abbrev_journal'])) {
            // abbreviated journal name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['abbrev_journal'] . $markupPatternsArray["italic-suffix"];
        }
        if ((!empty($row['abbrev_journal']) || !empty($row['publication'])) && (!empty($row['volume']) || !empty($row['issue']))) {
            $record .= ",";
        }
        // NOTE: for newspaper articles, the above mentioned guide uses a dot instead of a comma ("The Times, 3 Sep. p.4-5.") but this seems incorrect/inconsistent to me
        if ($row['online_publication'] == "yes") {
            // this record refers to an online publication
            $record .= " [Online]";
        }
        if ($row['type'] == "Journal Article") {
            if (!empty($row['volume'])) {
                // volume
                $record .= " " . $row['volume'];
            }
            if (!empty($row['issue'])) {
                if (!empty($row['volume'])) {
                    $record .= " ";
                }
                $record .= "(" . $row['issue'] . ")";
            }
        } elseif (preg_match("/^(Newspaper Article|Magazine Article)\$/", $row['type'])) {
            if (!empty($row['issue'])) {
                // issue (=day)
                $record .= " " . $row['issue'];
            }
            if (!empty($row['volume'])) {
                // volume (=month)
                $record .= " " . $row['volume'];
            }
        }
        if (!empty($row['pages'])) {
            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
                $record .= ", ";
            }
            $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p. ", "p. ");
            // function 'formatPageInfo()' is defined in 'cite.inc.php' (NOTE: from the examples in the above mentioned guide it's unclear whether "p." should be followed by a space or not)
        }
        if ($row['online_publication'] == "yes") {
            // append an optional string (given in 'online_citation') plus the current date and the DOI (or URL):
            if (!empty($row['online_citation'])) {
                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
                    $record .= ",";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi']) || !empty($row['url'])) {
                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
                    $record .= ".";
                }
                $today = date("j F Y");
                $record .= " Available at: " . $markupPatternsArray["underline-prefix"];
                if (!empty($row['doi'])) {
                    // doi
                    $uri = "http://dx.doi.org/" . $row['doi'];
                } else {
                    // url
                    $uri = $row['url'];
                }
                if ($encodeHTML) {
                    $record .= encodeHTML($uri);
                } else {
                    $record .= $uri;
                }
                $record .= $markupPatternsArray["underline-suffix"];
                $record .= " [accessed " . $today . "]";
            }
        }
        if (!preg_match("/\\. *\$/", $record)) {
            // if the string doesn't end with a period
            $record .= ".";
        }
    } elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", " " . $markupPatternsArray["ampersand"] . " ", "/ *, */", ", ", ", ", ".", false, false, true, "4", "1", " et al", $encodeHTML);
            // 16.
            $record .= $author;
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= ", ";
            }
            $record .= $row['year'];
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= ". ";
            }
            $record .= $row['title'];
            $record .= ".";
        }
        // From here on we'll assume that at least one of the fields 'author', 'year' or 'title' did contain some contents
        // 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)
        if (!empty($row['editor'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", " " . $markupPatternsArray["ampersand"] . " ", "/ *, */", " ", " ", ".", true, true, true, "4", "1", " et al", $encodeHTML);
            // 16.
            $record .= " In " . $editor . ", ";
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= "eds.";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= "ed.";
            }
        }
        $publication = preg_replace("/[ \r\n]*\\(Eds?:[^\\)\r\n]*\\)/i", "", $row['publication']);
        if (!empty($publication)) {
            if (empty($row['editor'])) {
                $record .= " In";
            }
            $record .= " " . $markupPatternsArray["italic-prefix"] . $publication . $markupPatternsArray["italic-suffix"];
        }
        if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition']) || !empty($row['volume'])) {
            $record .= ". ";
            if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
                if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                    if ($row['edition'] == "2") {
                        $editionSuffix = "nd";
                    } elseif ($row['edition'] == "3") {
                        $editionSuffix = "rd";
                    } else {
                        $editionSuffix = "th";
                    }
                } else {
                    $editionSuffix = "";
                }
                if (!empty($row['edition']) && !preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                    $editionSuffix .= " ed.";
                }
                $record .= $row['edition'] . $editionSuffix;
            }
            if (!empty($row['volume'])) {
                if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
                    $record .= ", ";
                }
                $record .= "vol. " . $row['volume'];
                // TODO: not sure whether this is correct
            }
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            $record .= ". ";
            if (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            } elseif (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            }
            // abbreviated series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= ", ";
            }
            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)
                $record .= "vol. " . $row['series_volume'];
            }
            // TODO: not sure whether this is correct
            if (!empty($row['series_issue'])) {
                if (!empty($row['series_volume'])) {
                    $record .= ", ";
                }
                $record .= "no. " . $row['series_issue'];
                // TODO: not sure whether this is correct
            }
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
        if (!empty($row['place'])) {
            // place
            $record .= " " . $row['place'];
        }
        if (!empty($row['publisher'])) {
            if (!empty($row['place'])) {
                $record .= ":";
            }
            $record .= " " . $row['publisher'];
        }
        if (!empty($row['pages'])) {
            if (!empty($row['publisher']) || !empty($row['place'])) {
                $record .= ", ";
            }
            $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p. ", "p. ");
            // function 'formatPageInfo()' is defined in 'cite.inc.php' (NOTE: from the examples in the above mentioned guide it's unclear whether "p." should be followed by a space or not)
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
    } else {
        if (!empty($row['author'])) {
            $author = preg_replace("/[ \r\n]*\\(eds?\\)/i", "", $row['author']);
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($author, true, "/ *; */", ", ", " " . $markupPatternsArray["ampersand"] . " ", "/ *, */", ", ", ", ", ".", false, false, true, "4", "1", " et al", $encodeHTML);
            // 16.
            // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
            // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
            //  so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
            if (preg_match("/[ \r\n]*\\(ed\\)/", $row['author'])) {
                // single editor
                $author = $author . " ed.";
            } elseif (preg_match("/[ \r\n]*\\(eds\\)/", $row['author'])) {
                // multiple editors
                $author = $author . " eds.";
            }
            $record .= $author;
        }
        if (!empty($row['year'])) {
            if (!empty($row['author'])) {
                $record .= ", ";
            }
            $record .= $row['year'];
        }
        if (!empty($row['title'])) {
            if (!empty($row['author']) || !empty($row['year'])) {
                $record .= ". ";
            }
            $record .= $markupPatternsArray["italic-prefix"] . $row['title'] . $markupPatternsArray["italic-suffix"];
        }
        if ($row['online_publication'] == "yes") {
            // this record refers to an online publication
            $record .= ". [Online]";
        }
        // TODO: this may not be entirely correct, since, according to the above mentioned guide, the actual type should be used: e.g. "[e-book]" or "[CD-ROM]"
        if (!empty($row['editor']) && !preg_match("/[ \r\n]*\\(eds?\\)/", $row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", " " . $markupPatternsArray["ampersand"] . " ", "/ *, */", " ", " ", ".", true, true, true, "4", "1", " et al", $encodeHTML);
            // 16.
            if (!empty($row['author']) || !empty($row['year']) || !empty($row['title'])) {
                $record .= " ";
            }
            $record .= " (" . $editor . ", ";
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= "eds.";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= "ed.";
            }
            $record .= ")";
        }
        if (!empty($row['edition']) || !empty($row['volume'])) {
            if (!empty($row['author']) || !empty($row['year']) || !empty($row['title']) || !empty($row['editor']) && !preg_match("/[ \r\n]*\\(eds?\\)/", $row['author'])) {
                $record .= ". ";
            }
            if ($row['type'] == "Software") {
                if (!empty($row['edition'])) {
                    $record .= "Version " . $row['edition'];
                    if (!empty($row['volume']) || !empty($row['issue'])) {
                        $record .= ", ";
                    }
                }
                if (!empty($row['issue'])) {
                    // issue (=day)
                    $record .= " " . $row['issue'];
                }
                if (!empty($row['volume'])) {
                    // volume (=month)
                    $record .= " " . $row['volume'];
                }
            } elseif (!preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
                if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                    if ($row['edition'] == "2") {
                        $editionSuffix = "nd";
                    } elseif ($row['edition'] == "3") {
                        $editionSuffix = "rd";
                    } else {
                        $editionSuffix = "th";
                    }
                } else {
                    $editionSuffix = "";
                }
                if (!empty($row['edition']) && !preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                    $editionSuffix .= " ed.";
                }
                $record .= $row['edition'] . $editionSuffix;
                if (!empty($row['volume'])) {
                    if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
                        $record .= ", ";
                    }
                    $record .= "vol. " . $row['volume'];
                    // TODO: not sure whether this is correct
                }
            }
        }
        if ($row['type'] == "Software") {
            $record .= ", computer software.";
        } else {
            if (!preg_match("/\\. *\$/", $record)) {
                $record .= ".";
            }
            if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
                $record .= " ";
                if (!empty($row['series_title'])) {
                    $record .= $row['series_title'];
                } elseif (!empty($row['abbrev_series_title'])) {
                    $record .= $row['abbrev_series_title'];
                }
                // abbreviated series title
                if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                    $record .= ", ";
                }
                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)
                    $record .= "vol. " . $row['series_volume'];
                }
                // TODO: not sure whether this is correct
                if (!empty($row['series_issue'])) {
                    if (!empty($row['series_volume'])) {
                        $record .= ", ";
                    }
                    $record .= "no. " . $row['series_issue'];
                    // TODO: not sure whether this is correct
                }
                $record .= ".";
            }
        }
        if (!empty($row['thesis'])) {
            // thesis
            $record .= " " . $row['thesis'];
        }
        if (!empty($row['place']) || !empty($row['publisher'])) {
            if (!empty($row['thesis'])) {
                $record .= ".";
            }
            if (!empty($row['place'])) {
                // place (NOTE: should we omit the place of publication for theses?)
                $record .= " " . $row['place'];
            }
            if (!empty($row['publisher'])) {
                if (!empty($row['place'])) {
                    $record .= ":";
                }
                $record .= " " . $row['publisher'];
            }
        }
        if ($row['online_publication'] == "yes" || $row['type'] == "Software") {
            if (!empty($row['online_citation'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi']) || !empty($row['url'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                $today = date("j F Y");
                $record .= " Available at: " . $markupPatternsArray["underline-prefix"];
                if (!empty($row['doi'])) {
                    // doi
                    $uri = "http://dx.doi.org/" . $row['doi'];
                } else {
                    // url
                    $uri = $row['url'];
                }
                if ($encodeHTML) {
                    $record .= encodeHTML($uri);
                } else {
                    $record .= $uri;
                }
                $record .= $markupPatternsArray["underline-suffix"];
                $record .= " [accessed " . $today . "]";
            }
        }
        if (!preg_match("/\\. *\$/", $record)) {
            // if the string doesn't end with a period
            $record .= ".";
        }
    }
    // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
    // do some further cleanup:
    $record = trim($record);
    // remove any preceding or trailing whitespace
    return $record;
}
Exemple #3
0
function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
{
    $record = "";
    // make sure that our buffer variable is empty
    // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
    if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", and ", "/ *, */", ", ", " ", ". ", false, true, false, "3", "1", ", et al.", $encodeHTML);
            // 16.
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= '"' . $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
            $record .= '"';
        }
        // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
        // 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)
        if (!empty($row['abbrev_journal'])) {
            // abbreviated journal name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['abbrev_journal'] . $markupPatternsArray["italic-suffix"];
        } elseif (!empty($row['publication'])) {
            // publication (= journal) name
            $record .= " " . $markupPatternsArray["italic-prefix"] . $row['publication'] . $markupPatternsArray["italic-suffix"];
        }
        if (!empty($row['volume'])) {
            if (!empty($row['abbrev_journal']) || !empty($row['publication'])) {
                $record .= ".";
            }
            $record .= " " . $row['volume'];
        }
        if (!empty($row['issue'])) {
            // issue
            $record .= "." . $row['issue'];
        }
        if (!empty($row['year'])) {
            $record .= " (" . $row['year'] . ")";
        }
        if ($row['online_publication'] == "yes") {
            // instead of any pages info (which normally doesn't exist for online publications) we append
            // an optional string (given in 'online_citation') plus the current date and the DOI (or URL):
            $today = date("j M. Y");
            if (!empty($row['online_citation'])) {
                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
                    $record .= ":";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi'])) {
                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
                    $record .= ".";
                }
                if ($encodeHTML) {
                    $record .= " " . $today . encodeHTML(" <http://dx.doi.org/" . $row['doi'] . ">");
                } else {
                    $record .= " " . $today . " <http://dx.doi.org/" . $row['doi'] . ">";
                }
            } elseif (!empty($row['url'])) {
                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
                    $record .= ".";
                }
                if ($encodeHTML) {
                    $record .= " " . $today . encodeHTML(" <" . $row['url'] . ">");
                } else {
                    $record .= " " . $today . " <" . $row['url'] . ">";
                }
            }
        } else {
            if (!empty($row['pages'])) {
                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
                    $record .= ": ";
                }
                $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"]);
                // function 'formatPageInfo()' is defined in 'cite.inc.php'
            }
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
    } elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", and ", "/ *, */", ", ", " ", ". ", false, true, false, "3", "1", ", et al.", $encodeHTML);
            // 16.
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= '"' . $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
            $record .= '"';
        }
        $publication = preg_replace("/[ \r\n]*\\(Eds?:[^\\)\r\n]*\\)/i", "", $row['publication']);
        if (!empty($publication)) {
            // publication
            $record .= " " . $markupPatternsArray["italic-prefix"] . $publication . $markupPatternsArray["italic-suffix"];
        }
        // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
        // 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)
        if (!empty($row['editor'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", ", and ", "/ *, */", " ", " ", ". ", true, true, false, "3", "1", ", et al.", $encodeHTML);
            // 16.
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= " Eds. " . $editor;
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= " Ed. " . $editor;
            }
        }
        if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                if ($row['edition'] == "2") {
                    $editionSuffix = "nd";
                } elseif ($row['edition'] == "3") {
                    $editionSuffix = "rd";
                } else {
                    $editionSuffix = "th";
                }
            } else {
                $editionSuffix = "";
            }
            if (preg_match("/^(Rev\\.?|Revised)( ed\\.?| edition)?\$/i", $row['edition'])) {
                $row['edition'] = "Rev.";
            } elseif (preg_match("/^(Abr\\.?|Abridged)( ed\\.?| edition)?\$/i", $row['edition'])) {
                $row['edition'] = "Abr.";
            }
            if (!preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                $editionSuffix .= " ed.";
            }
            $record .= " " . $row['edition'] . $editionSuffix;
        }
        if (!empty($row['volume'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " Vol. " . $row['volume'];
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " ";
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= ", ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            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)
                $record .= "." . $row['series_issue'];
            }
            // is it correct to format series issues similar to journal article issues?
        }
        if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
            $record .= ".";
        }
        if (!empty($row['place'])) {
            // place
            $record .= " " . $row['place'];
        }
        if (!empty($row['publisher'])) {
            if (!empty($row['place'])) {
                $record .= ":";
            }
            $record .= " " . $row['publisher'];
        }
        if (!empty($row['year'])) {
            $record .= ", " . $row['year'];
        }
        if (!empty($row['pages'])) {
            // pages
            $record .= ". " . formatPageInfo($row['pages'], $markupPatternsArray["endash"]);
        }
        // function 'formatPageInfo()' is defined in 'cite.inc.php'
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
    } else {
        if (!empty($row['author'])) {
            $author = preg_replace("/[ \r\n]*\\(eds?\\)/i", "", $row['author']);
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($author, true, "/ *; */", ", ", ", and ", "/ *, */", ", ", " ", ". ", false, true, false, "3", "1", ", et al.", $encodeHTML);
            // 16.
            // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
            // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
            //  so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
            if (preg_match("/[ \r\n]*\\(ed\\)/", $row['author'])) {
                // single editor
                $author = $author . ", " . "ed";
            } elseif (preg_match("/[ \r\n]*\\(eds\\)/", $row['author'])) {
                // multiple editors
                $author = $author . ", " . "eds";
            }
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            if (!empty($row['thesis'])) {
                $record .= '"' . $row['title'];
                if (!preg_match("/[?!.]\$/", $row['title'])) {
                    $record .= ".";
                }
                $record .= '"';
            } else {
                // not a thesis
                $record .= $markupPatternsArray["italic-prefix"] . $row['title'] . $markupPatternsArray["italic-suffix"];
            }
        }
        if (!empty($row['editor']) && !preg_match("/[ \r\n]*\\(eds?\\)/", $row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", ", and ", "/ *, */", " ", " ", ". ", true, true, false, "3", "1", ", et al.", $encodeHTML);
            // 16.
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= " Eds. " . $editor;
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= " Ed. " . $editor;
            }
        }
        if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                if ($row['edition'] == "2") {
                    $editionSuffix = "nd";
                } elseif ($row['edition'] == "3") {
                    $editionSuffix = "rd";
                } else {
                    $editionSuffix = "th";
                }
            } else {
                $editionSuffix = "";
            }
            if (preg_match("/^(Rev\\.?|Revised)( ed\\.?| edition)?\$/i", $row['edition'])) {
                $row['edition'] = "Rev.";
            } elseif (preg_match("/^(Abr\\.?|Abridged)( ed\\.?| edition)?\$/i", $row['edition'])) {
                $row['edition'] = "Abr.";
            }
            if (!preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                $editionSuffix .= " ed.";
            }
            $record .= " " . $row['edition'] . $editionSuffix;
        }
        if (!empty($row['volume'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " Vol. " . $row['volume'];
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " ";
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= ", ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            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)
                $record .= "." . $row['series_issue'];
            }
            // is it correct to format series issues similar to journal article issues?
        }
        if (!empty($row['thesis'])) {
            // TODO: a published dissertation needs to be formatted differently!
            //       see e.g. example at: <http://web.csustan.edu/english/reuben/pal/append/AXI.HTML>
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            // TODO: I've also seen MLA examples that separate thesis name, name of institution and year by dots. ?:-|
            //       Also, do we need to use the abbreviation "Diss." instead of "Ph.D. thesis"? What about other thesis types then?
            //       see e.g. <http://www.english.uiuc.edu/cws/wworkshop/writer_resources/citation_styles/mla/unpublished_diss.htm>
            $record .= " " . $row['thesis'];
            $record .= ", " . $row['publisher'];
        } else {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (!empty($row['place'])) {
                // place
                $record .= " " . $row['place'];
            }
            if (!empty($row['publisher'])) {
                if (!empty($row['place'])) {
                    $record .= ":";
                }
                $record .= " " . $row['publisher'];
            }
        }
        if (!empty($row['year'])) {
            // year
            $record .= ", " . $row['year'];
        }
        if ($row['online_publication'] == "yes") {
            $today = date("j M. Y");
            if (!empty($row['online_citation'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                if ($encodeHTML) {
                    $record .= " " . $today . encodeHTML(" <http://dx.doi.org/" . $row['doi'] . ">");
                } else {
                    $record .= " " . $today . " <http://dx.doi.org/" . $row['doi'] . ">";
                }
            } elseif (!empty($row['url'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                if ($encodeHTML) {
                    $record .= " " . $today . encodeHTML(" <" . $row['url'] . ">");
                } else {
                    $record .= " " . $today . " <" . $row['url'] . ">";
                }
            }
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
    }
    // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
    // do some further cleanup:
    $record = trim($record);
    // remove any preceding or trailing whitespace
    return $record;
}
function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
{
    global $alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, $print, $punct, $space, $upper, $word, $patternModifiers;
    // defined in 'transtab_unicode_charset.inc.php' and 'transtab_latin1_charset.inc.php'
    $record = "";
    // make sure that our buffer variable is empty
    // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
    if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "", "", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            $record .= $author . " ";
        }
        if (!empty($row['year'])) {
            // year
            $record .= "(" . $row['year'] . ") ";
        }
        if (!empty($row['title'])) {
            $record .= $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
            $record .= " ";
        }
        if (!empty($row['abbrev_journal'])) {
            // abbreviated journal name
            $record .= $row['abbrev_journal'] . " ";
        } elseif (!empty($row['publication'])) {
            // publication (= journal) name
            $record .= $row['publication'] . " ";
        }
        if (!empty($row['volume'])) {
            // volume
            $record .= $row['volume'];
        }
        if (!empty($row['issue'])) {
            // issue
            $record .= "(" . $row['issue'] . ")";
        }
        if ($row['online_publication'] == "yes") {
            // instead of any pages info (which normally doesn't exist for online publications) we append
            // an optional string (given in 'online_citation') plus the DOI:
            if (!empty($row['online_citation'])) {
                if (!empty($row['volume']) || !empty($row['issue'])) {
                    // only add ":" if either volume or issue isn't empty
                    $record .= ":";
                }
                $record .= " " . $row['online_citation'];
            }
            if (!empty($row['doi'])) {
                // doi
                $record .= " doi:" . $row['doi'];
            }
        } else {
            if (!empty($row['pages'])) {
                if (!empty($row['volume']) || !empty($row['issue'])) {
                    // only add ":" if either volume or issue isn't empty
                    $record .= ":";
                }
                $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "", "", " pp");
                // function 'formatPageInfo()' is defined in 'cite.inc.php'
            }
        }
    } elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "", "", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            $record .= $author . " ";
        }
        if (!empty($row['year'])) {
            // year
            $record .= "(" . $row['year'] . ") ";
        }
        if (!empty($row['title'])) {
            $record .= $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
            $record .= " ";
        }
        if (!empty($row['editor'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "", "", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            $record .= "In: " . $editor;
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= " (eds)";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= " (ed)";
            }
        }
        $publication = preg_replace("/[ \r\n]*\\(Eds?:[^\\)\r\n]*\\)/i", "", $row['publication']);
        if (!empty($publication)) {
            // publication
            $record .= " " . $publication . ". ";
        } else {
            if (!empty($row['editor'])) {
                $record .= ". ";
            }
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= " ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            if (!empty($row['series_issue'])) {
                // series issue
                $record .= "(" . $row['series_issue'] . ")";
            }
            if (!empty($row['pages'])) {
                $record .= ", ";
            }
        } else {
            if (!empty($row['publisher'])) {
                $record .= $row['publisher'];
                if (!empty($row['place'])) {
                    $record .= ", ";
                } else {
                    if (!preg_match("/,\$/", $row['publisher'])) {
                        $record .= ",";
                    }
                    $record .= " ";
                }
            }
            if (!empty($row['place'])) {
                $record .= $row['place'];
                if (!empty($row['pages'])) {
                    if (!preg_match("/,\$/", $row['place'])) {
                        $record .= ",";
                    }
                    $record .= " ";
                }
            }
        }
        if (!empty($row['pages'])) {
            // pages
            $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p ", "pp ", " pp");
        }
        // function 'formatPageInfo()' is defined in 'cite.inc.php'
    } else {
        if (!empty($row['author'])) {
            $author = preg_replace("/[ \r\n]*\\(eds?\\)/i", "", $row['author']);
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($author, true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "", "", " " . $markupPatternsArray["italic-prefix"] . "and __NUMBER_OF_AUTHORS__ others" . $markupPatternsArray["italic-suffix"], $encodeHTML);
            // 16.
            $record .= $author . " ";
        }
        if (!empty($row['year'])) {
            // year
            $record .= "(" . $row['year'] . ") ";
        }
        if (!empty($row['title'])) {
            $record .= $row['title'];
            if (!preg_match("/[?!.]\$/", $row['title'])) {
                $record .= ".";
            }
            $record .= " ";
        }
        if (!empty($row['thesis'])) {
            // thesis
            $record .= $row['thesis'] . ". ";
        }
        if (!empty($row['publisher'])) {
            $record .= $row['publisher'];
            if (!empty($row['place'])) {
                $record .= ", ";
            } else {
                if (!preg_match("/,\$/", $row['publisher'])) {
                    $record .= ",";
                }
                $record .= " ";
            }
        }
        if (!empty($row['place'])) {
            $record .= $row['place'];
            if (!empty($row['abbrev_series_title']) || !empty($row['series_title']) || !empty($row['pages'])) {
                if (!preg_match("/,\$/", $row['place'])) {
                    $record .= ",";
                }
                $record .= " ";
            }
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!empty($row['abbrev_series_title'])) {
                $record .= $row['abbrev_series_title'];
            } elseif (!empty($row['series_title'])) {
                $record .= $row['series_title'];
            }
            // full series title
            // series volume & series issue will get appended only if there's also either the full or an abbreviated series title(!):
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= " ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= $row['series_volume'];
            }
            if (!empty($row['series_issue'])) {
                // series issue
                $record .= "(" . $row['series_issue'] . ")";
            }
            if (!empty($row['pages'])) {
                if (!preg_match("/,\$/", $row['series_volume'])) {
                    $record .= ",";
                }
                $record .= " ";
            }
        }
        if (!empty($row['pages'])) {
            // TODO: use function 'formatPageInfo()' when it can recognize & process total number of pages
            //						$record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p ", "pp ", " pp"); // function 'formatPageInfo()' is defined in 'cite.inc.php'
            if (preg_match("/\\d *[{$dash}] *\\d/{$patternModifiers}", $row['pages'])) {
                // if the 'pages' field contains a page range (like: "127-132")
                // Note that we'll check for page ranges here although for whole books the 'pages' field should NOT contain a page range but the total number of pages! (like: "623 pp")
                $pagesDisplay = preg_replace("@(\\d+) *[{$dash}] *(\\d+)@{$patternModifiers}", "\\1" . $markupPatternsArray["endash"] . "\\2", $row['pages']);
            } else {
                $pagesDisplay = $row['pages'];
            }
            $record .= $pagesDisplay;
        }
    }
    // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
    // do some further cleanup:
    $record = preg_replace("/[.,][ \r\n]*\$/i", "", $record);
    // remove '.' or ',' at end of line
    if ($citeStyle == "MEPS") {
        // if '$citeStyle' = 'MEPS' ...
        $record = preg_replace("/pp ([0-9]+)/i", "p \\1", $record);
    }
    // ... replace 'pp' with 'p' in front of (book chapter) page numbers
    return $record;
}
Exemple #5
0
function generateCalculationFieldContent($author, $pages, $volume, $seriesVolume)
{
    if (!empty($author)) {
        // Standardize contents of the author field (which will ensure correct sorting upon Citation output):
        // - shorten author's full given name(s) to initial(s)
        // - remove any delimiters (such as dots and/or whitespace) from author's initials
        // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
        //   1. input:  contents of the author field
        //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
        //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
        //
        //   3. input:  pattern describing old delimiter that separates different authors
        //   4. output: for all authors except the last author: new delimiter that separates different authors
        //   5. output: for the last author: new delimiter that separates the last author from all other authors
        //
        //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
        //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
        //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
        //   9. output: new delimiter that separates multiple initials (within one author)
        //  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)
        //  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)
        //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
        //
        //  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
        //  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
        //  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
        //
        //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
        $author = reArrangeAuthorContents($author, true, "/ *; */", "; ", "; ", "/ *, */", ", ", ", ", "", false, false, true, "", "", "", false);
        // 16.
        // 'first_author' field:
        $firstAuthor = preg_replace("/^([^;]+).*/i", "\\1", $author);
        // extract first author from 'author' field
        $firstAuthor = trim($firstAuthor);
        // remove leading & trailing whitespace (if any)
        $firstAuthor = preg_replace("/ *\\(eds?\\)\$/i", "", $firstAuthor);
        // remove any existing editor info from the 'first_author' string, i.e., kill any trailing " (ed)" or " (eds)"
        // 'author_count' field:
        if (!preg_match("/;/", $author)) {
            // if the 'author' field does NOT contain a ';' (which would delimit multiple authors) => single author
            $authorCount = "1";
        } elseif (preg_match("/^[^;]+;[^;]+\$/", $author)) {
            // the 'author' field does contain exactly one ';' => two authors
            $authorCount = "2";
        } elseif (preg_match("/^[^;]+;[^;]+;[^;]+/", $author)) {
            // the 'author' field does contain at least two ';' => more than two authors
            $authorCount = "3";
        }
        // indicates three (or more) authors
    } else {
        $firstAuthor = "";
        $authorCount = "";
    }
    // 'first_page' field:
    if (!empty($pages)) {
        if (preg_match("/([0-9]+)/", $pages)) {
            // if the 'pages' field contains any numeric value(s)
            $firstPage = preg_replace("/^[^0-9]*([0-9]+).*/i", "\\1", $pages);
        } else {
            $firstPage = "";
        }
    } else {
        $firstPage = "";
    }
    // 'volume_numeric' field:
    if (!empty($volume)) {
        if (preg_match("/([0-9]+)/", $volume)) {
            // if the 'volume' field contains any numeric value(s)
            $volumeNumeric = preg_replace("/^[^0-9]*([0-9]+).*/i", "\\1", $volume);
        } else {
            $volumeNumeric = "";
        }
    } else {
        $volumeNumeric = "";
    }
    // 'series_volume_numeric' field:
    if (!empty($seriesVolume)) {
        if (preg_match("/([0-9]+)/", $seriesVolume)) {
            // if the 'series_volume' field contains any numeric value(s)
            $seriesVolumeNumeric = preg_replace("/^[^0-9]*([0-9]+).*/i", "\\1", $seriesVolume);
        } else {
            $seriesVolumeNumeric = "";
        }
    } else {
        $seriesVolumeNumeric = "";
    }
    return array($firstAuthor, $authorCount, $firstPage, $volumeNumeric, $seriesVolumeNumeric);
}
Exemple #6
0
function standardizePersonNames($nameString, $familyNameFirst, $personDelimiter, $familyNameGivenNameDelimiter, $shortenGivenNames)
{
    // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the 'author', 'editor' or 'series_editor' field. Required Parameters:
    //   1. input:  contents of the author field
    //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
    //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
    //
    //   3. input:  pattern describing old delimiter that separates different authors
    //   4. output: for all authors except the last author: new delimiter that separates different authors
    //   5. output: for the last author: new delimiter that separates the last author from all other authors
    //
    //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
    //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
    //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
    //   9. output: new delimiter that separates multiple initials (within one author)
    //  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)
    //  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)
    //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
    //
    //  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
    //  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
    //  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
    //
    //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
    $reorderedNameString = reArrangeAuthorContents($nameString, $familyNameFirst, $personDelimiter, "; ", "; ", $familyNameGivenNameDelimiter, ", ", ", ", ".", false, false, $shortenGivenNames, "", "", "", false);
    // 16.
    return $reorderedNameString;
}
function citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, $encodeHTML)
{
    global $alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, $print, $punct, $space, $upper, $word, $patternModifiers;
    // defined in 'transtab_unicode_charset.inc.php' and 'transtab_latin1_charset.inc.php'
    static $uspsStateAbbreviations;
    // Official USPS state abbreviations:
    // see <http://www.usps.com/ncsc/lookups/usps_abbreviations.htm>
    $uspsStateAbbreviations = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|" . "NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY";
    $record = "";
    // make sure that our buffer variable is empty
    // --- BEGIN TYPE = JOURNAL ARTICLE / MAGAZINE ARTICLE / NEWSPAPER ARTICLE --------------------------------------------------------------
    if (preg_match("/^(Journal Article|Magazine Article|Newspaper Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "6", "6", ", et al.", $encodeHTML);
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['title'];
        }
        // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
        // 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)
        if (!preg_match("/[?!.] *\$/", $record)) {
            $record .= ".";
        }
        if (!empty($row['abbrev_journal'])) {
            // abbreviated journal name
            $record .= " " . preg_replace("/\\./", "", $row['abbrev_journal']);
        } elseif (!empty($row['publication'])) {
            // publication (= journal) name
            $record .= " " . $row['publication'];
        }
        if ($row['online_publication'] == "yes") {
            // this record refers to an online publication
            $record .= " [Internet]";
        }
        // NOTE: some of the above mentioned resources use "[serial online]", "[serial on the Internet]" or just "[online]" instead
        // NOTE: the formatting of year/volume/issue is meant for journal articles (TODO: newspaper/magazine articles)
        if (!empty($row['year'])) {
            // year
            $record .= ". " . $row['year'];
        }
        if ($row['online_publication'] == "yes") {
            // append the current date if this record refers to an online publication
            $record .= " [cited " . date("Y M j") . "]";
        }
        if (!empty($row['volume']) || !empty($row['issue'])) {
            $record .= ";";
        }
        if (!empty($row['volume'])) {
            // volume (=month)
            $record .= $row['volume'];
        }
        if (!empty($row['issue'])) {
            // issue (=day)
            $record .= "(" . $row['issue'] . ")";
        }
        if (!empty($row['pages'])) {
            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
                $record .= ":";
            }
            $record .= formatPageInfo($row['pages'], $markupPatternsArray["endash"], "", "", "", "", "", "", true);
            // function 'formatPageInfo()' is defined in 'cite.inc.php'
        }
        if ($row['online_publication'] == "yes") {
            // append an optional string (given in 'online_citation') plus the DOI (or URL):
            if (!empty($row['online_citation'])) {
                if (!empty($row['year']) || !empty($row['volume']) || !empty($row['issue']) || !empty($row['abbrev_journal']) || !empty($row['publication'])) {
                    if (empty($row['pages'])) {
                        $record .= ":";
                    } else {
                        $record .= ";";
                    }
                    // append to pages (TODO: not sure whether this is correct)
                }
                $record .= $row['online_citation'];
            }
            if (!empty($row['doi']) || !empty($row['url'])) {
                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
                    $record .= ".";
                }
                $record .= " Available from: " . $markupPatternsArray["underline-prefix"];
                // NOTE: some of the above mentioned resources use "Available from: URL:http://..." instead
                if (!empty($row['doi'])) {
                    // doi
                    $uri = "http://dx.doi.org/" . $row['doi'];
                } else {
                    // url
                    $uri = $row['url'];
                }
                if ($encodeHTML) {
                    $record .= encodeHTML($uri);
                } else {
                    $record .= $uri;
                }
                $record .= $markupPatternsArray["underline-suffix"];
            }
        }
        if (!preg_match("/\\. *\$/", $record) and $row['online_publication'] != "yes") {
            $record .= ".";
        }
        // NOTE: the examples in the above mentioned resources differ wildly w.r.t. whether the closing period should be omitted for online publications
    } elseif (preg_match("/^(Abstract|Book Chapter|Conference Article)\$/", $row['type'])) {
        if (!empty($row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($row['author'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "6", "6", ", et al.", $encodeHTML);
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['title'];
        }
        if ($row['type'] == "Abstract") {
            // for abstracts, add "[abstract]" label
            $record .= " [abstract]";
        }
        // From here on we'll assume that at least either the 'author' or the 'title' field did contain some contents
        // 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)
        if (!empty($row['editor'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "6", "6", ", et al.", $encodeHTML);
            if (!preg_match("/[?!.] *\$/", $record)) {
                $record .= ".";
            }
            $record .= " In: " . $editor . ", ";
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= "editors";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= "editor";
            }
        }
        $publication = preg_replace("/[ \r\n]*\\(Eds?:[^\\)\r\n]*\\)/i", "", $row['publication']);
        if (!empty($publication)) {
            if (!preg_match("/[?!.] *\$/", $record)) {
                $record .= ".";
            }
            if (empty($row['editor'])) {
                $record .= " In:";
            }
            $record .= " " . $publication;
        }
        if (!empty($row['volume'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " Vol " . $row['volume'];
            // TODO: not sure whether this is correct
        }
        if (!empty($row['edition']) && !preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                if ($row['edition'] == "2") {
                    $editionSuffix = "nd";
                } elseif ($row['edition'] == "3") {
                    $editionSuffix = "rd";
                } else {
                    $editionSuffix = "th";
                }
            } else {
                $editionSuffix = "";
            }
            if (!preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                $editionSuffix .= " ed.";
            }
            $record .= " " . $row['edition'] . $editionSuffix;
        }
        if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
            $record .= ".";
        }
        if (!empty($row['place'])) {
            // for places in the USA, format any two-letter postal code for the state (i.e. ensure upper case & wrap in parens, eg. "Boca Raton (FL)"):
            if (preg_match("/(.+?)[{$punct}{$space}]+({$uspsStateAbbreviations})[{$punct}{$space}]*\$/i{$patternModifiers}", $row['place'])) {
                $record .= " " . preg_replace("/(.+?)[{$punct}{$space}]+({$uspsStateAbbreviations})[{$punct}{$space}]*\$/ie{$patternModifiers}", "'\\1 ('.strtoupper('\\2').')'", $row['place']);
            } else {
                $record .= " " . $row['place'];
            }
        }
        if (!empty($row['publisher'])) {
            if (!empty($row['place'])) {
                $record .= ":";
            }
            $record .= " " . $row['publisher'];
        }
        if (!empty($row['year'])) {
            // year
            $record .= "; " . $row['year'];
        }
        if (!empty($row['pages'])) {
            // pages
            $record .= ". " . formatPageInfo($row['pages'], $markupPatternsArray["endash"], "p. ", "p. ", "", "", "", "", true);
        }
        // function 'formatPageInfo()' is defined in 'cite.inc.php'
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " (";
            if (!empty($row['abbrev_series_title'])) {
                // abbreviated series title
                $record .= preg_replace("/\\./", "", $row['abbrev_series_title']);
            } elseif (!empty($row['series_title'])) {
                // full series title
                $record .= $row['series_title'];
            }
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= "; ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= "vol " . $row['series_volume'];
            }
            if (!empty($row['series_volume']) && !empty($row['series_issue'])) {
                $record .= "; ";
            }
            // TODO: not sure whether this is correct
            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)
                $record .= "no " . $row['series_issue'];
            }
            // since a series volume should be prefixed with "vol", is it correct to prefix series issues with "no"?
            $record .= ")";
        }
        if (!preg_match("/\\. *\$/", $record)) {
            $record .= ".";
        }
    } else {
        if (!empty($row['author'])) {
            $author = preg_replace("/[ \r\n]*\\(eds?\\)/i", "", $row['author']);
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $author = reArrangeAuthorContents($author, true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "6", "6", ", et al.", $encodeHTML);
            // if the author is actually the editor of the resource we'll append ', ed' (or ', eds') to the author string:
            // [to distinguish editors from authors in the 'author' field, the 'modify.php' script does append ' (ed)' or ' (eds)' if appropriate,
            //  so we're just checking for these identifier strings here. Alternatively, we could check whether the editor field matches the author field]
            if (preg_match("/[ \r\n]*\\(ed\\)/", $row['author'])) {
                // single editor
                $author = $author . ", editor";
            } elseif (preg_match("/[ \r\n]*\\(eds\\)/", $row['author'])) {
                // multiple editors
                $author = $author . ", editors";
            }
            if (!preg_match("/\\. *\$/", $author)) {
                $record .= $author . ".";
            } else {
                $record .= $author;
            }
        }
        if (!empty($row['title'])) {
            if (!empty($row['author'])) {
                $record .= " ";
            }
            $record .= $row['title'];
        }
        if ($row['type'] == "Software") {
            // for software, add software label
            $record .= " [computer program]";
        }
        if ($row['online_publication'] == "yes" and empty($row['thesis'])) {
            // this record refers to an online publication (online theses will be handled further down below)
            $record .= " [Internet]";
        }
        // NOTE: some of the above mentioned resources use "[monograph online]", "[monograph on the Internet]" or just "[online]" instead
        if (!empty($row['volume']) and $row['type'] != "Software") {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " Vol " . $row['volume'];
            // TODO: not sure whether this is correct
        }
        if (!empty($row['edition'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            if ($row['type'] == "Software") {
                $record .= " Version " . $row['edition'];
            } elseif (!preg_match("/^(1|1st|first|one)( ed\\.?| edition)?\$/i", $row['edition'])) {
                if (preg_match("/^\\d{1,3}\$/", $row['edition'])) {
                    if ($row['edition'] == "2") {
                        $editionSuffix = "nd";
                    } elseif ($row['edition'] == "3") {
                        $editionSuffix = "rd";
                    } else {
                        $editionSuffix = "th";
                    }
                } else {
                    $editionSuffix = "";
                }
                if (!preg_match("/( ed\\.?| edition)\$/i", $row['edition'])) {
                    $editionSuffix .= " ed.";
                }
                $record .= " " . $row['edition'] . $editionSuffix;
            }
        }
        if (!empty($row['editor']) && !preg_match("/[ \r\n]*\\(eds?\\)/", $row['author'])) {
            // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
            //   1. input:  contents of the author field
            //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
            //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
            //
            //   3. input:  pattern describing old delimiter that separates different authors
            //   4. output: for all authors except the last author: new delimiter that separates different authors
            //   5. output: for the last author: new delimiter that separates the last author from all other authors
            //
            //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
            //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
            //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
            //   9. output: new delimiter that separates multiple initials (within one author)
            //  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)
            //  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)
            //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
            //
            //  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
            //  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
            //  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
            //
            //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
            $editor = reArrangeAuthorContents($row['editor'], true, "/ *; */", ", ", ", ", "/ *, */", " ", " ", "", false, false, true, "6", "6", ", et al.", $encodeHTML);
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " " . $editor;
            if (preg_match("/^[^;\r\n]+(;[^;\r\n]+)+\$/", $row['editor'])) {
                // there are at least two editors (separated by ';')
                $record .= ", editors";
            } else {
                // there's only one editor (or the editor field is malformed with multiple editors but missing ';' separator[s])
                $record .= ", editor";
            }
        }
        if (!empty($row['thesis'])) {
            // TODO: do we need to use the term "[dissertation]" instead of "[Ph.D. thesis]", etc? What about other thesis types then?
            $record .= " [" . $row['thesis'];
            if ($row['online_publication'] == "yes") {
                // this record refers to an online thesis
                $record .= " on the Internet]";
            } else {
                $record .= "]";
            }
        }
        if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
            $record .= ".";
        }
        if (!empty($row['place'])) {
            // for places in the USA, format any two-letter postal code for the state (i.e. ensure upper case & wrap in parentheses, eg. "Boca Raton (FL)"):
            if (preg_match("/(.+?)[{$punct}{$space}]+({$uspsStateAbbreviations})[{$punct}{$space}]*\$/i{$patternModifiers}", $row['place'])) {
                $record .= " " . preg_replace("/(.+?)[{$punct}{$space}]+({$uspsStateAbbreviations})[{$punct}{$space}]*\$/ie{$patternModifiers}", "'\\1 ('.strtoupper('\\2').')'", $row['place']);
            } else {
                $record .= " " . $row['place'];
            }
        }
        if (!empty($row['publisher'])) {
            if (!empty($row['place'])) {
                $record .= ":";
            }
            $record .= " " . $row['publisher'];
        }
        $record .= ";";
        if (!empty($row['year'])) {
            // year
            $record .= " " . $row['year'];
        }
        if ($row['type'] == "Software") {
            if (!empty($row['volume'])) {
                // volume (=month)
                $record .= " " . $row['volume'];
            }
            if (!empty($row['issue'])) {
                // issue (=day)
                $record .= " " . $row['issue'];
            }
        }
        if ($row['online_publication'] == "yes") {
            // append the current date if this record refers to an online publication
            $record .= " [cited " . date("Y M j") . "]";
        }
        if (!empty($row['abbrev_series_title']) or !empty($row['series_title'])) {
            if (!preg_match("@[?!.][ \"" . $markupPatternsArray["italic-suffix"] . "]*\$@", $record)) {
                $record .= ".";
            }
            $record .= " (";
            if (!empty($row['abbrev_series_title'])) {
                // abbreviated series title
                $record .= preg_replace("/\\./", "", $row['abbrev_series_title']);
            } elseif (!empty($row['series_title'])) {
                // full series title
                $record .= $row['series_title'];
            }
            if (!empty($row['series_volume']) || !empty($row['series_issue'])) {
                $record .= "; ";
            }
            if (!empty($row['series_volume'])) {
                // series volume
                $record .= "vol " . $row['series_volume'];
            }
            if (!empty($row['series_volume']) && !empty($row['series_issue'])) {
                $record .= "; ";
            }
            // TODO: not sure whether this is correct
            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)
                $record .= "no " . $row['series_issue'];
            }
            // since a series volume should be prefixed with "vol", is it correct to prefix series issues with "no"?
            $record .= ")";
        }
        if ($row['online_publication'] == "yes" || $row['type'] == "Software") {
            // append an optional string (given in 'online_citation') plus the DOI (or URL):
            if (!empty($row['online_citation'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                $record .= $row['online_citation'];
            }
            if (!empty($row['doi']) || !empty($row['url'])) {
                if (!preg_match("/\\. *\$/", $record)) {
                    $record .= ".";
                }
                $record .= " Available from: " . $markupPatternsArray["underline-prefix"];
                // NOTE: some of the above mentioned resources use "Available from: URL:http://..." instead
                if (!empty($row['doi'])) {
                    // doi
                    $uri = "http://dx.doi.org/" . $row['doi'];
                } else {
                    // url
                    $uri = $row['url'];
                }
                if ($encodeHTML) {
                    $record .= encodeHTML($uri);
                } else {
                    $record .= $uri;
                }
                $record .= $markupPatternsArray["underline-suffix"];
            }
        }
        if (!preg_match("/\\. *\$/", $record) and $row['online_publication'] != "yes" and $row['type'] != "Software") {
            $record .= ".";
        }
        // NOTE: the examples in the above mentioned resources differ wildly w.r.t. whether the closing period should be omitted for online publications
    }
    // --- BEGIN POST-PROCESSING -----------------------------------------------------------------------------------------------------------
    // do some further cleanup:
    $record = trim($record);
    // remove any preceding or trailing whitespace
    return $record;
}
function getPersons($personString, $standardizePersonNames = true, $betweenNamesDelim = "/ *; */", $nameGivenDelim = "/ *, */", $newBetweenGivensDelim = ".")
{
    if ($standardizePersonNames) {
        // NOTE: We standardize person names (e.g. add dots between initials if missing) in an attempt to adhere to
        //       the recommendations given at <http://eprints-uk.rdn.ac.uk/project/docs/simpledc-guidelines/#creator>
        //
        // Call the 'reArrangeAuthorContents()' function (defined in 'include.inc.php') in order to re-order contents of the author field. Required Parameters:
        //   1. input:  contents of the author field
        //   2. input:  boolean value that specifies whether the author's family name comes first (within one author) in the source string
        //              ('true' means that the family name is followed by the given name (or initials), 'false' if it's the other way around)
        //
        //   3. input:  pattern describing old delimiter that separates different authors
        //   4. output: for all authors except the last author: new delimiter that separates different authors
        //   5. output: for the last author: new delimiter that separates the last author from all other authors
        //
        //   6. input:  pattern describing old delimiter that separates author name & initials (within one author)
        //   7. output: for the first author: new delimiter that separates author name & initials (within one author)
        //   8. output: for all authors except the first author: new delimiter that separates author name & initials (within one author)
        //   9. output: new delimiter that separates multiple initials (within one author)
        //  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)
        //  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)
        //  12. output: boolean value that specifies whether an author's full given name(s) shall be shortened to initial(s)
        //
        //  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
        //  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
        //  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
        //
        //  16. output: boolean value that specifies whether the re-ordered string shall be returned with higher ASCII chars HTML encoded
        $personString = reArrangeAuthorContents($personString, true, $betweenNamesDelim, "; ", "; ", $nameGivenDelim, ", ", ", ", $newBetweenGivensDelim, false, false, true, "", "", "", false);
        // 16.
        $betweenNamesDelim = "/\\s*;\\s*/";
    }
    $nameArray = array();
    if (!preg_match("#^/.*/\$#", $betweenNamesDelim)) {
        $betweenNamesDelim = "/" . $betweenNamesDelim . "/";
    }
    // add search pattern delimiters
    $nameArray = preg_split($betweenNamesDelim, $personString, -1, PREG_SPLIT_NO_EMPTY);
    // get a list of all authors/editors
    return $nameArray;
}