#!/usr/bin/python

######################################################################
#  Use GNU source-hightlight to turn source code into pango markup
#  and pipe to paps.
#
#  This is currently of limited use for long lines, as the paps/pango
#  line breaking algorithm will insert hyphens in the text.
#
#  2023-01-14 Sat
# Dov Grobgeld <dov.grobgeld@gmail.com>
######################################################################

import argparse
import subprocess
from pathlib import Path
import sys
import tempfile

def xec(cmd, decode=True, chomp=True, verbose=False):
  '''Run a command a returns its stdout output.

  decode -- run (utf8) decode of the resulting string
  chomp -- get rid of the last newline (like in perl)
  '''
  ph = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
  if verbose:
    sys.stderr.write(cmd + '\n')
  res = b''
  maxsize = 1024
  while True:
    buf = ph.stdout.read()
    if len(buf)==0:
      break
    res += buf
  ph.wait()
  if decode:
    res=res.decode()
  if chomp:
    res = res[:-1]
  return res

def arg_if_not_none(param_name, val):
  '''Return either an empty string or the parameter with its value'''
  if val is None:
    return ''
  return param_name + ' ' + val + ' '

# Defaults

# TBD - Make this a configuration variable
pango_outlang_path = '/usr/local/share/paps/pango_markup.outlang'

parser = argparse.ArgumentParser(description='Process a file')
parser.add_argument('-o', '--output',
                    dest='output',
                    action='store',
                    type=str,
                    default='-',
                    help='Output filename')
parser.add_argument('-v', '--verbose',
                    dest='verbose',
                    action='store_true',
                    help='Verbose editing')
parser.add_argument('--pango-outlang-path',
                    dest='pango_outlang_path',
                    action='store',
                    type =str,
                    default = pango_outlang_path,
                    help='Path to pango_markup.outlang')
parser.add_argument('-s', '--source-lang',
                    dest='source_lang',
                    action='store',
                    type =str,
                    default = None,
                    help='Override the source lang')
parser.add_argument('--style-file',
                    dest='style_file',
                    action='store',
                    type =str,
                    default = None,
                    help='Set a style file for syntax highlight')
parser.add_argument('--style-css-file',
                    dest='style_css_file',
                    action='store',
                    type =str,
                    default = None,
                    help='Set a style file for syntax highlight')

# TBD add additional paps variables, or pass them verbatim
parser.add_argument('--columns',
                    dest='columns',
                    action='store',
                    type =int,
                    default = 1,
                    help='Number of columns in paps output')
parser.add_argument('--landscape',
                    dest='landscape',
                    action='store_true',
                    help='Output landscape')
parser.add_argument('--font',
                    dest='font',
                    action='store',
                    default='',
                    help='Paps font')
parser.add_argument('filename', nargs='*', help='Input. Default is stdin')
args = parser.parse_args()
Output = args.output

# Create the pmu file
markups = []
for fn in args.filename:
  source_lang = ({'.py' : 'python',
                  '.cpp' : 'C',
                  '.cxx' : 'C',
                  '.cc'  : 'C',
                  '.c'   : 'C'
                  }.get(Path(fn).suffix)
                 if args.source_lang is None
                 else args.source_lang)

  markups.append(
    xec(f'source-highlight '
        + (f'-s {source_lang} ' if source_lang is not None else '')
        + arg_if_not_none('--style-file', args.style_file)
        + arg_if_not_none('--style-css-file', args.style_css_file)
        + f'--outlang-def {args.pango_outlang_path} '
        f'--input {fn}',
        verbose=args.verbose))

with tempfile.TemporaryDirectory() as tmp:
  pmu_file = Path(tmp) / 'src-to-paps.pmu'

  with open(pmu_file,'w') as ofh:
    ofh.write('----'.join(markups))
  
  title =','.join(args.filename)
  
  output_args = f'-o {Output} ' if Output!='-' else ''
  
  xec(f'paps  --header '
      f'{"--landscape " if args.landscape else ""}'
      f'--columns {args.columns} '
      f'--separation-lines '
      f'--markup '
      f'--header-center "{title}" '
      + (f' --font "{args.font}" ' if len else "")
      + f'--header-left "{{now:%c}}" '
      f'--header-right="Page {{page_idx}}/{{num_pages}}" '
      '--format pdf '
      '--wrap=char '
      '--show-wrap '
      f'{output_args}'
      f'{pmu_file} ',
      verbose=args.verbose)
