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
27 import sys
28 import re
29
30 replacement_sets = []
31
32 # -------------------------------------
33 # Read replacement sets from .fncs file
34 # -------------------------------------
35
36 def 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
76 if len(sys.argv) < 2:
77 sys.exit('Usage: {} FILE1.FNCS [FILE2.FNCS...]'.format(sys.argv[0]))
78
79 fout = sys.stdout
80
81 for input_fn in sys.argv[1:]:
82 read_fncs_file(input_fn)
83
84 # process template for each replacement set
85 for 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)