/* LAYOUT.mffm  version 1.1 */
/* Run this macro from within the MFF citation database containing */
/* citations to be exported.  It writes a word processor-compatible */
/* file with each record (citation) laid out according to the format */
/* specified in the LAYOUT template file selected by the user. */


/* The following tables summarize the embedded word processing codes */
/* needed to turn on/off special formatting features in the laid out */
/* citations.  These codes will function after the output citation */
/* file is imported (retrieved) into the word processor.  The codes */
/* used in this macro are designed to be compatible with WordPerfect */
/* or Microsoft Word (Rich Text Format).  It should be possible to */
/* substitute codes for most other word processors with equivalent */
/* results. */


/* WordPerfect formatting codes */

      WP_Bold_ON = d2c(157);
     WP_Bold_OFF = d2c(156);
   WP_Italics_ON = d2c(178);
  WP_Italics_OFF = d2c(179);
 WP_Underline_ON = d2c(148);
WP_Underline_OFF = d2c(149); 
          Header = d2c(128);
       WP_Header = (Header || Header);


/* Microsoft Word (Rich Text Format) formatting codes */

      MS_Bold_ON = '{\b ';
     MS_Bold_OFF = '}';
   MS_Italics_ON = '{\i ';
  MS_Italics_OFF = '}';
 MS_Underline_ON = '{\ul ';
MS_Underline_OFF = '}';
    MS_Paragraph = '\par ';
          MS_EOF = '}';
     MS_Header_1 = '{\rtf0\mac {\fonttbl{\f2\froman New York;}}{\stylesheet{';
     MS_Header_2 = '\sbasedon222\snext0 Normal;}}\widowctrl\ftnbj\ftnrestart \sectd \linemod0\linex0\cols1\colsx0\endnhere \pard\plain ';


/* make sure some records are selected */
options results;
options failat 20;
first;
if (rc ~= 0) then;
  do;
    display 'You must select some records to export!';
    exit;
  end;

/* open the text file for export */
/* NOTE: change the disk/drive designations below to suit your setup */
screentofront();
out_text = getfile(,,'ram:',,'Select export file name');
if (out_text = '') then exit;
if (open(exportfile,out_text,'W') ~= 1) then;
  do;
    screentoback();
    display 'I could not open the file ' || out_text || ' for exporting.';
    exit;
  end;


/* request user to select output file type (WordPerfect or MS_Word) */
/* and assign embedded formatting characters accordingly */
wp_type = request(,,'Choose output file type for laid out citations:',,'WordPerfect','Microsoft Word/Rich Text Format',);
if (wp_type = 'OKAY') then;
  do;
          wp_type = 'WordPerfect';
          Bold_ON = WP_Bold_ON;
         Bold_OFF = WP_Bold_OFF;
       Italics_ON = WP_Italics_ON;
      Italics_OFF = WP_Italics_OFF;
     Underline_ON = WP_Underline_ON;
    Underline_OFF = WP_Underline_OFF;
  end;
else;
  do;
          wp_type = 'Microsoft Word';
          Bold_ON = MS_Bold_ON;
         Bold_OFF = MS_Bold_OFF;
       Italics_ON = MS_Italics_ON;
      Italics_OFF = MS_Italics_OFF;
     Underline_ON = MS_Underline_ON;
    Underline_OFF = MS_Underline_OFF;
  end;
say 'Output file may be imported into ' || wp_type || '!';


/* open journal format template file for import */
template_file = getfile(,,'ram:',,'Select LAYOUT template file!');
if (open(importfile,template_file,'R') ~= 1) then;
  do;
    screentoback();
    display 'I could not open the file ' || template_file || ' for importing.';
    exit;
  end;

/* decode LAYOUT template */
/* sub.1.value = overall citation format */
/* sub.2.value = format around initials  */
/* sub.3.value = format around last author */
/* sub.4.value = format around next to last author */
/* sub.5.value = format around middle author */
/* sub.6.value = format around first author */
/* sub.7.value = special format for title words (e.g. species names)  */
/*     where i = italics, u = underline, b = bold, s = same, n = none */
template = readln(importfile);
parse var template sub.1.value '/' sub.2.value '/' sub.3.value '/' sub.4.value '/' sub.5.value '/' sub.6.value '/' sub.7.value '/';
say sub.1.value ||'/'|| sub.2.value ||'/'|| sub.3.value ||'/'|| sub.4.value ||'/'|| sub.5.value ||'/'|| sub.6.value ||'/'|| sub.7.value ||'/';


/* Title "toggle" character embedded word processor codes */
/* Assign '&' (Toggle_ON) code  */
/* Assign '$' (Toggle_OFF) code */
if sub.7.value = 'u' then;
  do;
    Toggle_ON  = Underline_ON;
    Toggle_OFF = Underline_OFF;
  end;
else;
if sub.7.value = 'b' then;
  do;
    Toggle_ON  = Bold_ON;
    Toggle_OFF = Bold_OFF;
  end;
else;
if sub.7.value = 'i' then;
  do;
    Toggle_ON  = Italics_ON;
    Toggle_OFF = Italics_OFF;
  end;
else;
if sub.7.value = 's' then;
  do;
    Toggle_ON  = '&';
    Toggle_OFF = '$';
  end;
else;
if sub.7.value = 'n' then;
  do;
    Toggle_ON  = '';
    Toggle_OFF = '';
  end;
else;
  exit;


/* get the first record */
get rec;
citation_number = 1;
default_number_string = '000';


/* read all of the records in the database and export them */
do while (rc = 0);
  author_string = compress(rec.1.value);
    year_string = rec.2.value;
   title_string = rec.3.value;
 short_j_string = rec.4.value;
  long_j_string = rec.5.value;


/* Replace title toggle characters with embedded word processor codes */
/* Replace '&' with Toggle_ON  */
/* Replace '$' with Toggle_OFF */
do forever;
  insert_pos = index(title_string,'&');
  if insert_pos = 0 then leave;
  title_string = insert(Toggle_ON,title_string,insert_pos);
  title_string = delstr(title_string,insert_pos,1);
end;
title_string = translate(title_string,Toggle_OFF,'$');


/* extract surnames and initials from author_string */
n = 1;
do forever;
  parse var author_string sur.n.value ',' author_string;
  if sur.n.value == '' then leave;
  parse var author_string init.n.value ',' author_string;
  n = n + 1;
end;
authornumber = n - 1;


/* extract abbreviated journal name, volume, first and last pages */
parse var short_j_string AbbJournal ',' volume ',' firstpage ',' lastpage ',';
      volume = compress(volume);
   firstpage = compress(firstpage);
    lastpage = compress(lastpage);

/* extract full journal name from long_j_string */
FullJournalLength = length(long_j_string);
FullJournal = right(long_j_string,(FullJournalLength-1));


/* LAYOUT citation using template */
uppercase = 0;
citation_string = '';
  do i = 1 to length(sub.1.value);
  x = substr(sub.1.value,i,1);
    if x = 'a' then;
      do j = 1 to authornumber;
        q = '';
        if ((j = 1) & (sub.6.value ~= '')) then q = sub.6.value;
        if ((j = authornumber) & (length(q) = 0)) then q = sub.3.value;
        if ((j = authornumber-1) & (length(q) = 0)) then q = sub.4.value;
        if (length(q) = 0) then q = sub.5.value;
        do k = 1 to length(q);
          subq = substr(q,k,1);
          if subq = 'S' then;
            do;
             uppercase = 1;
             citation_string = (citation_string || upper(sur.j.value));
            end;
          else;
          if subq = 's' then;
            citation_string = (citation_string || sur.j.value);
          else;
          if ((subq = '@') & (uppercase = 1)) then;
            citation_string = (citation_string || 'AND');
          else;
          if ((subq = '@') & (uppercase ~= 1)) then;
            citation_string = (citation_string || 'and');
          else;
          if subq = 'i' then;
            do;
              L = 1;
              Z = init.j.value;
              E = sub.2.value;
              do while L <= length(Z);
                do m = 1 to length(E);
                  if substr(E,m,1) = 'i' then;
                    do;
                      citation_string = (citation_string || substr(Z,L,1));
                      if substr(Z,L+1,1) >= 'a' then;
                        do;
                          citation_string = (citation_string || substr(Z,L+1,1));
                          L = L + 1;
                        end;
                      else NOP;
                    end;
                  else;
                    citation_string = (citation_string || substr(E,m,1));
                end;
                L = L + 1;
              end;
            end;
          else;
            citation_string = (citation_string || subq);
        end;
      end;
    temp_string = '';
    if (x = '<') then temp_string = Underline_ON;
    if (x = '>') then temp_string = Underline_OFF;
    if (x = '{') then temp_string = Bold_ON;
    if (x = '}') then temp_string = Bold_OFF;
    if (x = '[') then temp_string = Italics_ON;
    if (x = ']') then temp_string = Italics_OFF;
    if (x = 'J') then temp_string = FullJournal;
    if (x = 'j') then temp_string = AbbJournal;
    if (x = 'k') then temp_string = space(translate(AbbJournal,' ','. '),1);
    if (x = 't') then temp_string = title_string;
    if (x = 'v') then temp_string = volume;
    if (x = 'f') then temp_string = firstpage;
    if (x = 'l') then temp_string = lastpage;
    if (x = 'y') then temp_string = year_string;
    if (x = 'n') then temp_string = right((default_number_string || citation_number),3);
    if (length(temp_string) > 0) then;
      citation_string = (citation_string || temp_string);
    else;
    if (((x >= 'a') & (x <= 'z')) | ((x >= 'A') & (x <= 'Z'))) then;
      x = '';
    else;
      citation_string = (citation_string || x);
  end;


/* clean up citation_string */
  do forever;
    del_pos1 = index(citation_string,'.,.');
    if del_pos1 > 0 then citation_string = delstr(citation_string,del_pos1,2);
    del_pos2 = index(citation_string,' -.');
    if del_pos2 > 0 then citation_string = delstr(citation_string,del_pos2,3);
    del_pos3 = index(citation_string,'-.');
    if del_pos3 > 0 then citation_string = delstr(citation_string,del_pos3,1);
    del_pos4 = index(citation_string,'-,');
    if del_pos4 > 0 then citation_string = delstr(citation_string,del_pos4,1);
    del_pos5 = index(citation_string,',:');
    if del_pos5 > 0 then citation_string = delstr(citation_string,del_pos5,1);
    del_pos6 = index(citation_string,',.');
    if del_pos6 > 0 then citation_string = delstr(citation_string,del_pos6,1);
    del_pos7 = index(citation_string,',,');
    if del_pos7 > 0 then citation_string = delstr(citation_string,del_pos7,1);
    del_pos8 = index(citation_string,'..');
    if del_pos8 > 0 then citation_string = delstr(citation_string,del_pos8,1);
    if (del_pos1 + del_pos2 + del_pos3 + del_pos4 + del_pos5 + del_pos6 + del_pos7 + del_pos8) = 0 then leave;
  end;


/* write citation_string to output file */
  blankline = '';
  if citation_number = 1 then;
    do;
      if wp_type = 'WordPerfect' then;
        citation_string = (WP_Header || citation_string);
      else;
        do;
          foo = writeln(exportfile,MS_Header_1);
          citation_string = (MS_Header_2 || citation_string);
        end;
    end;
  else NOP;
  if wp_type = 'Microsoft Word' then;
    do;
      citation_string = (citation_string || MS_Paragraph);
      blankline = (blankline || MS_Paragraph);
    end;
  else NOP;
  say citation_string;
  say blankline;
  foo = writeln(exportfile,citation_string);
  foo = writeln(exportfile,blankline);


/* get next record/citation for layout or exit macro */
  next;
  if (rc ~= 0) then;
    do;
      if wp_type = 'Microsoft Word' then;
        foo = writech(exportfile,MS_EOF);
      else NOP;
      screentoback();
      display 'Citations laid out in the text file: ' || out_text;
      exit;
    end;
  else;
  citation_number = citation_number + 1;
  get rec;
end;
