aboutsummaryrefslogtreecommitdiffstats
path: root/generate_auto_job
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2023-12-23 03:03:47 +0100
committerJay Berkenbilt <ejb@ql.org>2023-12-23 03:22:34 +0100
commitc0c7cef16cb666524e4809834063cfee5262eca1 (patch)
tree38cb6da6567e7cbcac97766629d568363cd9ec16 /generate_auto_job
parent1f4568684341ec3a0abb0c7ce72580b07b73d646 (diff)
downloadqpdf-c0c7cef16cb666524e4809834063cfee5262eca1.tar.zst
Generate a UNIX man page (fixes #874)
Diffstat (limited to 'generate_auto_job')
-rwxr-xr-xgenerate_auto_job60
1 files changed, 56 insertions, 4 deletions
diff --git a/generate_auto_job b/generate_auto_job
index 10d74d89..d4143d5a 100755
--- a/generate_auto_job
+++ b/generate_auto_job
@@ -134,6 +134,12 @@ BANNER = f'''//
// clang-format off
//'''
+MAN_BANNER = f'''.\\"
+.\\" This file is automatically generated by {whoami}.
+.\\" Edits will be automatically overwritten if the build is
+.\\" run in maintainer mode.
+.\\"
+'''
def warn(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
@@ -156,9 +162,11 @@ class Main:
SOURCES = [
# Keep this list in sync with CMakeLists.txt: auto_job_inputs
whoami,
+ 'CMakeLists.txt',
'manual/_ext/qpdf.py',
'job.yml',
'manual/cli.rst',
+ 'manual/qpdf.1.in',
]
# DESTS is a map to the output files this code generates. These
# generated files, as well as those added to DESTS later in the
@@ -172,6 +180,7 @@ class Main:
'schema': 'libqpdf/qpdf/auto_job_schema.hh',
'json_decl': 'libqpdf/qpdf/auto_job_json_decl.hh',
'json_init': 'libqpdf/qpdf/auto_job_json_init.hh',
+ 'man': 'manual/qpdf.1',
# Others are added in top
}
# SUMS contains a checksum for each source and destination and is
@@ -277,7 +286,7 @@ class Main:
for k, v in hashes.items():
print(f'{k} {v}', file=f)
- def generate_doc(self, df, f):
+ def generate_doc(self, df, f, f_man):
st_top = 0
st_topic = 1
st_option = 2
@@ -324,6 +333,23 @@ class Main:
return True
return False
+ def manify(text):
+ lines = text.split('\n')
+ out = []
+ last_was_item = False
+ for line in lines:
+ if line.startswith('- '):
+ last_was_item = True
+ out.append('.IP \\[bu]')
+ out.append(line[2:])
+ elif last_was_item and line.startswith(' '):
+ out.append(line[2:])
+ else:
+ last_was_item = False
+ out.append(line)
+ return '\n'.join(out)
+
+ last_option_topic = ''
lineno = 0
for line in df.readlines():
if help_lines == 0:
@@ -366,6 +392,8 @@ class Main:
self.all_topics.add(topic)
print(f'ap.addHelpTopic("{topic}", "{short_text}",'
f' R"({long_text})");', file=f)
+ print(f'.SH {topic.upper()} ({short_text})', file=f_man)
+ print(manify(long_text), file=f_man, end='')
help_lines += 1
state = st_top
elif state == st_option:
@@ -389,6 +417,11 @@ class Main:
self.jdata[option[2:]]['help'] = short_text
print(f'ap.addOptionHelp("{option}", "{topic}",'
f' "{short_text}", R"({long_text})");', file=f)
+ if last_option_topic != topic:
+ print('.PP\nRelated Options:', file=f_man)
+ last_option_topic = topic
+ print(f'.TP\n.B {option} \\-\\- {short_text}', file=f_man)
+ print(manify(long_text), file=f_man, end='')
help_lines += 1
state = st_top
if help_lines == 20:
@@ -400,6 +433,11 @@ class Main:
print('ap.addHelpFooter("For detailed help, visit'
' the qpdf manual: https://qpdf.readthedocs.io\\n");', file=f)
print('}\n', file=f)
+ print('''.SH SEE ALSO
+.PP
+For a summary of qpdf's options, please run \\fBqpdf \\-\\-help\\fR.
+A complete manual can be found at https://qpdf.readthedocs.io.
+''', file=f_man, end='')
for i in self.referenced_topics:
if i not in self.all_topics:
raise Exception(f'help text referenced --help={i}')
@@ -412,6 +450,14 @@ class Main:
warn(f'{whoami}: regenerating auto job files')
self.validate(data)
+ version = None
+ with open('CMakeLists.txt', 'r') as f:
+ for line in f.readlines():
+ if line.strip().startswith('VERSION '):
+ version = line.strip().split(' ')[1]
+ if version is None:
+ raise Exception("can't read version from CMakeLists.txt")
+
# Keep track of which options are help options since they are
# handled specially. Add the built-in help options to tables
# that we populate as we read job.yml since we won't encounter
@@ -436,9 +482,15 @@ class Main:
for i in self.init:
print(i, file=f)
with write_file(self.DESTS['help']) as f:
- with open('manual/cli.rst', 'r') as df:
- print(BANNER, file=f)
- self.generate_doc(df, f)
+ with write_file(self.DESTS['man']) as f_man:
+ print(MAN_BANNER, file=f_man, end='')
+ with open('manual/qpdf.1.in', 'r') as m_in:
+ for line in m_in.readlines():
+ line = line.replace('@PROJECT_VERSION@', version)
+ print(line, file=f_man, end='')
+ with open('manual/cli.rst', 'r') as df:
+ print(BANNER, file=f)
+ self.generate_doc(df, f, f_man)
# Compute the json files after the config and arg parsing
# files. We need to have full information about all the