1
+ #!/usr/bin/env python3
2
+ """
3
+ Python script to generate a man page for the command `fastfetch`.
4
+ The man content will be printed to stdout so you will need to
5
+ pipe it to a file if you want to save it.
6
+ The command options will be generated using a JSON file.
7
+ For the format of the JSON file, see https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json
8
+ """
9
+
10
+ from json import load
11
+ from datetime import date
12
+ from re import search
13
+
14
+
15
+ ###### Text Decorations Tags ######
16
+
17
+ startUnderline = "\\ fI" # start underline text tag
18
+ endUnderline = "\\ fR" # end underline text tag
19
+
20
+ startBold = "\\ fB" # start bold text tag
21
+ endBold = "\\ fR" # end bold text tag
22
+
23
+
24
+ ###### Parameters ######
25
+
26
+ # path to the JSON option file
27
+ pathToHelpFile = "../src/data/help.json"
28
+ # man page section
29
+ manSection = 1
30
+ # title (center header)
31
+ titlePage = "Fastfetch man page"
32
+ # date (center footer)
33
+ todayDate = date .today ().strftime ("%b %d %Y" ) # format : "Month (abbreviation) Day Year"
34
+ # file to fastfetch version (left footer)
35
+ pathToVersionFile = "../CMakeLists.txt"
36
+
37
+
38
+ ###### Sections Text ######
39
+
40
+ # text displayed in the "NAME" section
41
+ nameSection = "\
42
+ fastfetch - a neofetch-like tool for fetching system \
43
+ information and displaying them in a pretty way"
44
+
45
+ # text displayed in the "DESCRIPTION" section
46
+ descriptionSection = "\
47
+ A maintained, feature-rich and performance \
48
+ oriented, neofetch like system information tool."
49
+
50
+ # text displayed at the beginning of the "OPTIONS" section
51
+ optionSection = "\
52
+ Parsing is not case sensitive. E.g. \\ fB--lib-PCI\\ fR \
53
+ is equal to \\ fB--Lib-Pci\\ fR. \
54
+ \n \n \
55
+ If a value is between square brakets, it is optional. \
56
+ An optional boolean value defaults to true if not \
57
+ specified. \
58
+ \n \n \
59
+ More detailed help messages for each options can be \
60
+ printed with \\ fB-h <option_without_dash_prefix>\\ fR. \
61
+ \n \n \
62
+ All options can be made permanent with command \
63
+ \\ fBfastfetch <options> --gen-config\\ fR. \
64
+ "
65
+
66
+ # text displayed in the "CONFIGURATION"
67
+ configurationSection = f"\
68
+ .SS Fetch Structure \n \
69
+ The structure of a fetch describes the modules that should \
70
+ be included in the output. It consists of a string of modules, \
71
+ separated by a colon (:). To list all available modules, \
72
+ use --list-modules \
73
+ \n \n \
74
+ .SS Config Files \n \
75
+ Fastfetch uses JSONC based format for configuration. \
76
+ Fastfetch doesn't generate config file automatically; \
77
+ it should be generated manually by { startBold } --gen-config.{ endBold } \
78
+ The config file will be saved in \
79
+ { startBold } ~/.config/fastfetch/config.jsonc{ endBold } by default. \
80
+ \n \n \
81
+ A JSONC config file is a JSON file that also supports comments \
82
+ with (// and /* */). Those files must have the extension '.jsonc'. \
83
+ \n \n \
84
+ The specified configuration/preset files are searched in the following order: \
85
+ \n \n \
86
+ { startBold } 1.{ endBold } relative to the current working directory \
87
+ \n \n \
88
+ { startBold } 2.{ endBold } relative to ~/.local/share/fastfetch/presets/ \
89
+ \n \n \
90
+ { startBold } 3.{ endBold } relative to /usr/share/fastfetch/presets/ \
91
+ \n \n \
92
+ Fastfetch provides some default presets. List them with --list-presets. \
93
+ "
94
+
95
+ # text displayed in the "EXAMPLE" section
96
+ exampleSection = "\
97
+ .SS Config files:\n \
98
+ .nf \
99
+ // ~/.config/fastfetch/config.jsonc \n \
100
+ {\n \
101
+ \" $schema\" : \" https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json\" ,\n \
102
+ \" modules\" : [ \n \
103
+ \" title\" , \n \
104
+ \" separator\" , \n \
105
+ \" module1\" , \n \
106
+ { \n \
107
+ \" type\" : \" module2\" , \n \
108
+ \" module2-option\" : \" value\" \n \
109
+ } \n \
110
+ ]\n \
111
+ } \n \
112
+ .fi"
113
+
114
+ # text displayed in the "BUGS" section
115
+ bugSection = "Please report bugs to : \
116
+ https://github.com/fastfetch-cli/fastfetch/issues"
117
+
118
+ # text displayed in the "WIKI" section
119
+ wikiSection = "Fastfetch github wiki : https://github.com/fastfetch-cli/fastfetch/wiki/Configuration"
120
+
121
+
122
+ ###### Argument decoration ######
123
+
124
+ ### optional arguments tags ###
125
+
126
+ # if an optional argument is displayed as [?optArg] (with "optArg" underlined)
127
+ # this value should be f"[?{startUnderline}"
128
+ startOptionalArgument = f"[{ startUnderline } ?"
129
+ # if an optional argument is displayed as [?optArg] (with "optArg underlined")
130
+ # this value should be f"{endUnderline}]"
131
+ endOptionalArgument = f"{ endUnderline } ]"
132
+
133
+ ### mandatory arguments tags ###
134
+ startMandatoryArgument = f"{ startUnderline } "
135
+ endMandatoryArgument = f"{ endUnderline } "
136
+
137
+ def generateManPage ():
138
+
139
+ # importing the JSON file
140
+ try :
141
+ with open (pathToHelpFile , 'r' ) as jsonFile :
142
+ helpFileData = load (jsonFile ) # json.load
143
+ jsonFile .close ()
144
+ except IOError as error :
145
+ print ("Error with file" , pathToHelpFile , ":" , error )
146
+ return
147
+
148
+
149
+ ######## Start printing the generated .1 file ########
150
+
151
+
152
+ ###### header, footer & config #####
153
+
154
+ print (f".TH man { manSection } " , end = " " )
155
+ print (f"\" { todayDate } \" " , end = " " )
156
+
157
+ # version number
158
+ try :
159
+ with open (pathToVersionFile , 'r' ) as versionFile :
160
+
161
+ # research version number in file with regex
162
+ for line in versionFile :
163
+ researchVersion = search ("^\s*VERSION (\d+\.\d+\.\d+)$" , line ) # re.search()
164
+ if (researchVersion != None ):
165
+ versionNumber = "" .join (line [researchVersion .start ():researchVersion .end ()].split (" " ))
166
+ versionNumber = versionNumber [:7 ] + " " + versionNumber [7 :]
167
+ break
168
+
169
+ versionFile .close ()
170
+ except IOError as error :
171
+ print ("Error with file" , pathToHelpFile , ":" , error )
172
+ return
173
+
174
+ print (f"\" { versionNumber } \" " , end = " " )
175
+ print (f"\" { titlePage } \" " )
176
+
177
+
178
+ ###### Name ######
179
+
180
+ print (".SH NAME" )
181
+ print (nameSection )
182
+
183
+
184
+ ##### Synopsis ######
185
+
186
+ print (".SH SYNOPSIS" )
187
+ print (".B fastfetch" )
188
+ print (f"[{ startUnderline } OPTIONS{ endUnderline } ]" )
189
+
190
+
191
+ ##### Description #####
192
+
193
+ print (".SH DESCRIPTION" )
194
+ print (descriptionSection )
195
+
196
+
197
+ ###### Wiki ######
198
+
199
+ print (".SH WIKI" )
200
+ print (wikiSection )
201
+
202
+
203
+ ###### Configuration ######
204
+
205
+ print (".SH CONFIGURATION" )
206
+ print (configurationSection )
207
+
208
+
209
+ ###### Options ######
210
+
211
+ print (".SH OPTIONS" )
212
+ print (optionSection )
213
+ print ()
214
+
215
+ # loop through every options sections
216
+ for key , value in helpFileData .items ():
217
+
218
+ # print new subsection
219
+ print (f".SS { key } :" )
220
+
221
+ # loop through every option in a section
222
+ for option in value :
223
+ # list of existing keys for this option
224
+ keyList = option .keys ()
225
+
226
+ # start a new "option" entry
227
+ print (".TP" )
228
+ print (startBold , end = "" )
229
+
230
+ # short option (-opt)
231
+ if "short" in keyList :
232
+ print (f"\\ -{ option ['short' ] } " , end = "" )
233
+ # if also have a long option, print a comma
234
+ if "long" in keyList :
235
+ print (", " , end = "" )
236
+
237
+ # long option (--option)
238
+ if "long" in keyList :
239
+ print (f"\\ -\\ -{ option ['long' ] } " , end = "" )
240
+
241
+ print (endBold , end = " " )
242
+
243
+ # arguments
244
+ if "arg" in keyList :
245
+ # if argument is optional, print "[arg]"
246
+ if "optional" in option ["arg" ].keys () and option ["arg" ]["optional" ]:
247
+ print (startOptionalArgument + option ['arg' ]['type' ] + endOptionalArgument , end = "" )
248
+
249
+ # if argument is mandatory, print "arg"
250
+ else :
251
+ print (startMandatoryArgument + option ['arg' ]['type' ] + endMandatoryArgument , end = "" )
252
+
253
+ # description
254
+ print (f"\n { option ['desc' ]} \n " )
255
+
256
+
257
+ ###### Examples ######
258
+
259
+ print (".SH EXAMPLES" )
260
+ print (exampleSection )
261
+
262
+
263
+ ###### Bugs ######
264
+
265
+ print (".SH BUGS" )
266
+ print (bugSection )
267
+
268
+
269
+
270
+
271
+
272
+ if __name__ == "__main__" :
273
+ generateManPage ()
0 commit comments