#! /usr/bin/env python

##############################################
# Extract each twemojis symbol to a separate #
# PDF file.                                  #
#                                            #
# In fact, this script creates only a Ninja  #
# build file to perform the operation.       #
#                                            #
# Author: Scott Pakin <scott-clsl@pakin.org> #
##############################################

import glob
import os
import re
import subprocess
import sys
import textwrap


def kpsewhich(fname):
    'Find a filename in the TeX tree.'
    proc = subprocess.run(['kpsewhich', fname], capture_output=True,
                          check=False, encoding='utf-8')
    if proc.returncode != 0:
        return None
    return proc.stdout.strip()


def header_string():
    'Return a "generated file" header string.'
    full_name = os.path.abspath(sys.argv[0])
    gen_line = 'This is a generated file.  DO NOT EDIT.'
    edit_line = f'Edit {full_name} instead.'
    max_chars = max(len(gen_line), len(edit_line))
    hash_line = '#' * (max_chars + 4)
    return '\n'.join([
        hash_line,
        '# %-*.*s #' % (max_chars, max_chars, gen_line),
        '# %-*.*s #' % (max_chars, max_chars, edit_line),
        hash_line,
        '',
    ])


def count_pdf_pages(fname):
    'Use pdfinfo to query the number of pages in a PDF file.'
    proc = subprocess.run(['pdfinfo', fname], capture_output=True,
                          check=True, encoding='utf-8')
    for ln in proc.stdout.split('\n'):
        fields = ln.split()
        if len(fields) == 2 and fields[0] == 'Pages:':
            return int(fields[1])
    raise RuntimeError(f'failed to count pages of {fname}')


# Generate a Ninja file that extracts each page of all-twemojis.pdf into a
# separate file.
with open('twemojis.ninja', 'w') as w:
    # Write the header string then stop if all-twemojis.pdf is unavailable.
    w.write(header_string())
    source_pdf = kpsewhich('all-twemojis.pdf')
    if source_pdf is None:
        w.write('')
        w.write('build TWEMOJIS : phony\n')
        sys.exit(0)

    # Define a rule that converts twemojis.sty to faketwemojis.sty.
    source_sty = kpsewhich('twemojis.sty')
    if source_sty is None:
        raise FileNotFoundError('No such file twemojis.sty')
    full_name = os.path.abspath(sys.argv[0])
    w.write(rf'''
rule fake-twemojis-sty
  command = $
    echo '%% This is a generated file.  DO NOT EDIT.' > $out ; $
    echo '%% Edit {full_name} instead.' >> $out ; $
    echo '' >> $out ; $''')
    w.write(r'''
    sed -e 's!\\includegraphics\[page=#1, ##1\]{all-twemojis.pdf}!\\includegraphics[##1]{twemojis/twemoji-#1}!' $in >> $out
  description = Generate $out from twemojis.sty

''')

    # Invoke the preceding rule.
    w.write(f'build faketwemojis.sty : fake-twemojis-sty {source_sty}\n')

    # Define a rule that extracts a single page of all-twemojis.pdf into a
    # separate file.
    w.write(f'''
rule extract-pdf-page
  command = pdfseparate -f $page -l $page $in 'twemojis/twemoji-%d.pdf'
  description = Extracting page $page from all-twemojis.pdf

''')

    # Invoke the preceding rule one for each page of all-twemojis.pdf.
    num_pages = count_pdf_pages(source_pdf)
    for i in range(1, num_pages + 1):
        w.write(f'build twemojis/twemoji-{i}.pdf : extract-pdf-page {source_pdf}\n')
        w.write(f'  page = {i}\n')
    w.write('\n')

    # Define a phony rule that depends on faketwemojis.sty and all of the
    # output files.
    w.write('build TWEMOJIS : phony $\n')
    phony = [f'twemojis/twemoji-{i}.pdf' for i in range(1, num_pages + 1)] + \
        ['faketwemojis.sty']
    lines = textwrap.wrap(' '.join(phony),
                          width=77,
                          break_long_words=False, break_on_hyphens=False,
                          initial_indent='  ', subsequent_indent='  ')
    w.write('%s\n' % ' $\n'.join(lines))
