1#!/usr/bin/env python3
2#
3# fontconfig/doc/extract-man-list.py
4#
5# Parses .fncs files and extracts list of man pages that will be generated
6#
7# Copyright © 2020 Tim-Philipp Müller
8#
9# Permission to use, copy, modify, distribute, and sell this software and its
10# documentation for any purpose is hereby granted without fee, provided that
11# the above copyright notice appear in all copies and that both that
12# copyright notice and this permission notice appear in supporting
13# documentation, and that the name of the author(s) not be used in
14# advertising or publicity pertaining to distribution of the software without
15# specific, written prior permission.  The authors make no
16# representations about the suitability of this software for any purpose.  It
17# is provided "as is" without express or implied warranty.
18#
19# THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21# EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25# PERFORMANCE OF THIS SOFTWARE.
26
27import sys
28import re
29
30replacement_sets = []
31
32# -------------------------------------
33# Read replacement sets from .fncs file
34# -------------------------------------
35
36def read_fncs_file(fn):
37  global replacement_sets
38
39  with open(fn, 'r', encoding='utf8') as f:
40    fncs_text = f.read()
41
42    # split into replacement sets
43    fncs_chunks = fncs_text.strip().split('@@')
44
45    for chunk in fncs_chunks:
46      # get rid of any preamble such as license and FcFreeTypeQueryAll decl in fcfreetype.fncs
47      start = chunk.find('@')
48      if start:
49        chunk = chunk[start:]
50
51      # split at '@' and remove empty lines (keep it simple instead of doing fancy
52      # things with regular expression matches, we control the input after all)
53      lines = [line for line in chunk.split('@') if line.strip()]
54
55      replacement_set = {}
56
57      while lines:
58        tag = lines.pop(0).strip()
59        # FIXME: this hard codes the tag used in funcs.sgml - we're lazy
60        if tag.startswith('PROTOTYPE'):
61          text = ''
62        else:
63          text = lines.pop(0).strip()
64          if text.endswith('%'):
65            text = text[:-1] + ' '
66
67        replacement_set[tag] = text
68
69      if replacement_set:
70        replacement_sets += [replacement_set]
71
72# ----------------------------------------------------------------------------
73#  Main
74# ----------------------------------------------------------------------------
75
76if len(sys.argv) < 2:
77  sys.exit('Usage: {} FILE1.FNCS [FILE2.FNCS...]'.format(sys.argv[0]))
78
79fout = sys.stdout
80
81for input_fn in sys.argv[1:]:
82  read_fncs_file(input_fn)
83
84# process template for each replacement set
85for rep in replacement_sets:
86  if 'FUNC+' in rep:
87    man_page_title = rep.get('TITLE', rep['FUNC'])
88  else:
89    man_page_title = rep['FUNC']
90  print(man_page_title)
91