#! /usr/bin/gawk -f
# Last edited on 2024-08-05 23:21:12 by stolfi

# Reads an arbitary file. Replaces all occurrences of the "{{Cite" or "{{cite" template by 
# a plain citation.

// {
  lot = ""
  lin = $0
  while (match(lin, /[{][{][ ]*[Cc]ite/)) {
    lot = ( lot substr(lin, 1, RSTART-1) )
    lin = substr(lin, RSTART + RLENGTH)
    if (match(lin, /^[^<>]*[}][}]/)) {
      cite = substr(lin, 1, RLENGTH-2)
      lin = substr(lin, RSTART + RLENGTH)
      lot = ( lot cleanup(cite) "<!--" cite "-->" )
    } else {
      data_error("cite not closed")
    }
  }
  lot = ( lot lin )
  print lot
  next
}

function data_error(msg) {
  printf "%s:%d: ** %s\n", FILENAME, FNR, msg > "/dev/stderr"
  printf "  «%s\n»\n", $0
}

function cleanup\
  ( cite,  \
    fld,n,i,x,m,mem,key,val,j,bugs,k,res,rtit,sep, \
    auth,doi,isbn,vol,issue,year,journal,series,title,url,page,pages,book \
  ) {
  
  # Collect fields:
  bugs = ""
  split("", auth)
  doi = ""
  isbn = ""
  vol = ""
  issue = ""
  year = ""
  title = ""
  journal = ""
  series = ""
  url = ""
  page = ""
  pages = ""
  book = 0
  n = split(cite, fld, "|")
  printf "n = %d\n", n > "/dev/stderr"
  for (i = 1; i <= n; i++) { 
    x = trim(fld[i])
    m = split(x, mem, "=")
    printf "  x = '%s' m = %d\n", x, m > "/dev/stderr"
    key = trim(mem[1])
    if (m == 1) {
      val  = ""
    } else {
      val = trim(mem[2])
      for (j = 3; j <= m; j++) {
        bugs = ( "[** key = " key " spurious val = " mem[j] "]") 
      }
    }
    
    if (match(key, /^first/)) {
      k = substr(key,6) + 0
      auth[k] = ( val " " auth[k] )
    } else if (match(key, /^last/)) {
      k = substr(key,5) + 0
      auth[k] = ( auth[k] " " val )
    } else if (match(key, /^author/)) {
      k = substr(key,7) + 0
      auth[k] = ( auth[k] " " val )
    } else if (match(key, /^volume$/)) {
      vol = val
    } else if (match(key, /^issue$/)) {
      issue = val
    } else if (match(key, /^pages$/)) {
      pages = val
    } else if (match(key, /^page$/)) {
      page = val
    } else if (match(key, /^year$/)) {
      year = val
    } else if (match(key, /^date$/)) {
      year = get_year(val)
    } else if (match(key, /^isbn$/)) {
      isbn = val
    } else if (match(key, /^doi$/)) {
      doi = val
    } else if (match(key, /^journal$/)) {
      journal = val
    } else if (match(key, /^series$/)) {
      series = val
    } else if (match(key, /^title$/)) {
      title = val
    } else if (match(key, /^url$/)) {
      url = val
    } else if (match(key, /^book$/)) {
      book = 1
    } else if (match(key, /^journal$/)) {
      book = 0
    } else {
      bugs = ( bugs "[** key = " key " val = " val "]" )
    }
  }
  
  # Assemble new citation:
  res = ""
  sep = ""
  for (k = 0; k <= 100; k++) {
    if (k in auth) { res = ( res sep auth[k] ) }
    sep = ", "
  }
  res = ( res " (" year "): " )
  rtit = ""
  if (book) {
    rtit = ( rtit "''" title "''" )
    if (journal != "") { bugs = ( bugs "[** journal with book = " journal "]" ) }
  } else {
    rtit = ( rtit "\"" title "\"" )
  }
  if (url != "") { rtit = ( "[" url " " rtit "]" ) }
  res = ( res rtit )
  if (journal != "") { res = ( res " ''" journal "''" ) }
  if (series != "") { res = ( res ", series " series ) }
  if (vol != "") { res = ( res ", volume " vol) }
  if (issue != "") { res = ( res ", issue " issue) }
  if (pages != "") { res = ( res ", pages " pages) }
  if (page != "") { res = ( res ", page " page) }
  res = ( res "." )
  if (doi != "") { res = ( res " {{doi|" doi "}}") }
  if (isbn != "") { res = ( res " {{isbn|" isbn "}}") }
  if (bugs != "") { res = ( res " " bugs ) }
  
  return res
}
    
function trim(x) {
  gsub(/^[ ]+/, "", x)
  gsub(/[ ]+$/, "", x)
  return x
}

function get_year(date) {
  if (match(date, /\<[12][0-9][0-9][0-9]\>/)) {
    return substr(date, RSTART, RLENGTH)
  } else {
    return date 
  }
}