1"""
2 pygments.lexers.scdoc
3 ~~~~~~~~~~~~~~~~~~~~~
4
5 Lexer for scdoc, a simple man page generator.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11import re
12
13from pygments.lexer import RegexLexer, include, bygroups, using, this
14from pygments.token import Text, Comment, Keyword, String, Generic
15
16__all__ = ['ScdocLexer']
17
18
19class ScdocLexer(RegexLexer):
20 """
21 `scdoc` is a simple man page generator for POSIX systems written in C99.
22 """
23 name = 'scdoc'
24 url = 'https://git.sr.ht/~sircmpwn/scdoc'
25 aliases = ['scdoc', 'scd']
26 filenames = ['*.scd', '*.scdoc']
27 version_added = '2.5'
28 flags = re.MULTILINE
29
30 tokens = {
31 'root': [
32 # comment
33 (r'^(;.+\n)', bygroups(Comment)),
34
35 # heading with pound prefix
36 (r'^(#)([^#].+\n)', bygroups(Generic.Heading, Text)),
37 (r'^(#{2})(.+\n)', bygroups(Generic.Subheading, Text)),
38 # bulleted lists
39 (r'^(\s*)([*-])(\s)(.+\n)',
40 bygroups(Text, Keyword, Text, using(this, state='inline'))),
41 # numbered lists
42 (r'^(\s*)(\.+\.)( .+\n)',
43 bygroups(Text, Keyword, using(this, state='inline'))),
44 # quote
45 (r'^(\s*>\s)(.+\n)', bygroups(Keyword, Generic.Emph)),
46 # text block
47 (r'^(```\n)([\w\W]*?)(^```$)', bygroups(String, Text, String)),
48
49 include('inline'),
50 ],
51 'inline': [
52 # escape
53 (r'\\.', Text),
54 # underlines
55 (r'(\s)(_[^_]+_)(\W|\n)', bygroups(Text, Generic.Emph, Text)),
56 # bold
57 (r'(\s)(\*[^*]+\*)(\W|\n)', bygroups(Text, Generic.Strong, Text)),
58 # inline code
59 (r'`[^`]+`', String.Backtick),
60
61 # general text, must come last!
62 (r'[^\\\s]+', Text),
63 (r'.', Text),
64 ],
65 }
66
67 def analyse_text(text):
68 """We checks for bold and underline text with * and _. Also
69 every scdoc file must start with a strictly defined first line."""
70 result = 0
71
72 if '*' in text:
73 result += 0.01
74
75 if '_' in text:
76 result += 0.01
77
78 # name(section) ["left_footer" ["center_header"]]
79 first_line = text.partition('\n')[0]
80 scdoc_preamble_pattern = r'^.*\([1-7]\)( "[^"]+"){0,2}$'
81
82 if re.search(scdoc_preamble_pattern, first_line):
83 result += 0.5
84
85 return result