#### markup.py
import markdown,sys ,keyword,cgi,re,requests,os

Page = "index"
if len(sys.argv) < 2: 
  Page = sys.argv[1]

Style   = "http://unbox.org/open/trunk/2014/markup"
Content = "http://unbox.org/open/trunk/2014/markup"

if Page == "reestablish":
  for file in ["markup.py", "index.cgi"]:
    r= requests.get(Content + "/" + file)
    with open(file, "wb") as code: 
      code.write(r.content)
  exit()

def say(x):   
  sys.stdout.write(str(x)); sys.stdout.flush()

class Lexer(object):
  """Originally from http://www.gooli.org/snippets/pylexer.py
     http://www.gooli.org/blog/a-simple-lexer-in-python/. 
     Suggested css entries:
      pre         { color: #666;   }
      ._class     { color: #000; font-weight: bold; }
      ._fun       { color: #000; font-weight: bold}
      ._comment   { color: #f79a32; }
      ._key       { color: Blue; font-weight: bold; }
      ._num       { color: #099; }
      ._op       { color: #000000; }
      ._str       { color: #d14; font-weight: bold; }"""
  patterns = {}
  patterns['py']= [
    ("_comment" ,r"#.*$"),
    ("_fun"      ,r"(?<=def )([A-Za-z_][A-Za-z0-9_]*)\s*(?=[(:])"),
    ("_class"    ,r"(?<=class )([A-Za-z_][A-Za-z0-9_]*)\s*(?=[(:])"),
    ("_key"      ,r"\b(%s)\b" % "|".join(keyword.kwlist)),
    ("_str"      ,r"[ru]?(\"([^\"\\]|(\\.))*\")|('([^\'\\]|(\\.))*')"),
    ("_op"      ,r"[%s]+" % re.escape("<>=*/+-~!%&()|{}[],.?:")),
    ("_ident"    ,r"[A-Za-z_][A-Za-z0-9_]*"),
    ("_num"      ,r"[0-9.]+"),
    ("_white"    ,r"\s+"),
    ("_other"    ,r".+")]
  def __init__(i,defs,numbers=True):
    i.n, i.numbers = 0, numbers
    i.definitions = defs
    str= "|".join(["(?P<%s>%s)" 
                     % (x,y) for x,y in defs])
    i.regexp = re.compile(str, re.MULTILINE)
  def tags(i, text):
    out = []
    for ako, value in i.parse(i.nums(text)):
      tmp= "<span class='%s'>%s</span>" % (ako,cgi.escape(value)) 
      out += [re.sub("\n","<br>",tmp)]
    return ''.join(out)
  def nums(i,text):
    if not i.numbers: return text
    empty   = re.compile('^[\t ]*$')
    lines,out = text.splitlines(),[]
    for line in lines:
      i.n += 1
      out += ['' if empty.match(line) 
                 else '%5s: %s' % (i.n,line)]
    return "\n".join(out)
  def parse(i, text):
    for match in i.regexp.finditer(text):
      for name, rexp in i.definitions:
        m = match.group(name)
        if m is not None:
          yield (name, m)
          break

def parse(str,fields=dict(Content='http://acadpub.org',
                      Style='http://acadpub.org',
                      Template='default')):
  """1) Turns headers in a dictionary;
     2_ Sends code fragments off to be highlighted"""
  lex = Lexer(Lexer.patterns['py'])
  header, txt, code    = {}, [], []
  headerp, codep, this = True, False, '0'
  header[this] = []
  def dumpCode(code):
    if code:
      tmp = '\n'.join(code)
      txt.extend(["<pre>"]+[lex.tags(tmp)]+["</pre>"])
    return []
  for line in str.splitlines():
    line = line.strip('\n')
    if re.search(r'^"""',line):
      codep =not codep
      if codep:
        code = []
      else:
        code = dumpCode(code)
    elif headerp:
      if not line: 
        for k,v in header.items():
          fields[k] = ', '.join(v)
        headerp=False
      else: 
        if re.search(r'^[ \t]+',line):
          header[this] += [line.strip()]
        else:
           parts = line.split(':')
           this  = parts[0].strip()
           that  = ':'.join(parts[1:]).strip()
           header[this] = [that] 
    else:
      if codep: code += [line]
      else:      txt  += [line]
  dumpCode(code)
  return fields,'\n'.join(txt)

def main(content=Content,style=Style,
         sep='!!!',xtend=[
          'footnotes', 'def_list',
          'tables','toc','meta'],
          fields   = dict(Content=Content,Style=Style,
                          Template='default')):
  body = requests.get(Content + "/" + Page).text
  fields,body = parse(body, fields)
  template = fields['Style'] + '/templates/' + fields['Template']
  head = requests.get(template + '/head.html').text
  foot = requests.get(template + '/foot.html').text
  txt  = markdown.Markdown(extensions=xtend).convert(
            head + body + foot)
  for i,part in enumerate(txt.split(sep)):
    say(fields.get(part,'???') if i % 2 else part)

main()
