]> jfr.im git - yt-dlp.git/blame - devscripts/prepare_manpage.py
[extractor] Framework for embed detection (#4307)
[yt-dlp.git] / devscripts / prepare_manpage.py
CommitLineData
cc52de43 1#!/usr/bin/env python3
54007a45 2
44c88923 3import optparse
1800eeef 4import os.path
1800eeef
PH
5import re
6
7ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
8README_FILE = os.path.join(ROOT_DIR, 'README.md')
9
7a5c1cfe 10PREFIX = r'''%yt-dlp(1)
44c88923
S
11
12# NAME
13
ec2e44fc 14yt\-dlp \- A youtube-dl fork with additional features and patches
44c88923
S
15
16# SYNOPSIS
17
7a5c1cfe 18**yt-dlp** \[OPTIONS\] URL [URL...]
44c88923 19
ec2e44fc 20# DESCRIPTION
21
44c88923
S
22'''
23
24
25def main():
26 parser = optparse.OptionParser(usage='%prog OUTFILE.md')
54007a45 27 _, args = parser.parse_args()
44c88923
S
28 if len(args) != 1:
29 parser.error('Expected an output filename')
30
31 outfile, = args
32
86e5f3ed 33 with open(README_FILE, encoding='utf-8') as f:
44c88923
S
34 readme = f.read()
35
ec2e44fc 36 readme = filter_excluded_sections(readme)
37 readme = move_sections(readme)
44c88923
S
38 readme = filter_options(readme)
39
86e5f3ed 40 with open(outfile, 'w', encoding='utf-8') as outf:
ec2e44fc 41 outf.write(PREFIX + readme)
42
43
44def filter_excluded_sections(readme):
45 EXCLUDED_SECTION_BEGIN_STRING = re.escape('<!-- MANPAGE: BEGIN EXCLUDED SECTION -->')
46 EXCLUDED_SECTION_END_STRING = re.escape('<!-- MANPAGE: END EXCLUDED SECTION -->')
47 return re.sub(
48 rf'(?s){EXCLUDED_SECTION_BEGIN_STRING}.+?{EXCLUDED_SECTION_END_STRING}\n',
49 '', readme)
50
51
52def move_sections(readme):
53 MOVE_TAG_TEMPLATE = '<!-- MANPAGE: MOVE "%s" SECTION HERE -->'
0fcba15d 54 sections = re.findall(r'(?m)^%s$' % (
55 re.escape(MOVE_TAG_TEMPLATE).replace(r'\%', '%') % '(.+)'), readme)
ec2e44fc 56
57 for section_name in sections:
58 move_tag = MOVE_TAG_TEMPLATE % section_name
59 if readme.count(move_tag) > 1:
60 raise Exception(f'There is more than one occurrence of "{move_tag}". This is unexpected')
61
62 sections = re.findall(rf'(?sm)(^# {re.escape(section_name)}.+?)(?=^# )', readme)
63 if len(sections) < 1:
64 raise Exception(f'The section {section_name} does not exist')
65 elif len(sections) > 1:
66 raise Exception(f'There are multiple occurrences of section {section_name}, this is unhandled')
67
68 readme = readme.replace(sections[0], '', 1).replace(move_tag, sections[0], 1)
69 return readme
44c88923 70
bad84757
YCH
71
72def filter_options(readme):
ec2e44fc 73 section = re.search(r'(?sm)^# USAGE AND OPTIONS\n.+?(?=^# )', readme).group(0)
74 options = '# OPTIONS\n'
75 for line in section.split('\n')[1:]:
08d30158 76 mobj = re.fullmatch(r'''(?x)
77 \s{4}(?P<opt>-(?:,\s|[^\s])+)
78 (?:\s(?P<meta>(?:[^\s]|\s(?!\s))+))?
79 (\s{2,}(?P<desc>.+))?
80 ''', line)
b440e1bb 81 if not mobj:
82 options += f'{line.lstrip()}\n'
83 continue
84 option, metavar, description = mobj.group('opt', 'meta', 'desc')
85
86 # Pandoc's definition_lists. See http://pandoc.org/README.html
87 option = f'{option} *{metavar}*' if metavar else option
88 description = f'{description}\n' if description else ''
89 options += f'\n{option}\n: {description}'
90 continue
ec2e44fc 91
92 return readme.replace(section, options, 1)
bad84757 93
582be358 94
44c88923
S
95if __name__ == '__main__':
96 main()