1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
|
#!/usr/bin/env python3
"""
Python script to generate a comprehensive man page for the command `fastfetch`.
The generated man page content will be printed to stdout,
so you will need to pipe it to a file if you want to save it.
Example: python3 gen-man.py > fastfetch.1
The command options are generated using a JSON file.
For the JSON file format, see:
https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json
"""
from json import load
from datetime import datetime, timezone
from time import time
from re import search
from os import environ, path
###### Text Decorations Tags ######
startUnderline = r"\fI" # start underline text tag
endUnderline = r"\fR" # end underline text tag
startBold = r"\fB" # start bold text tag
endBold = r"\fR" # end bold text tag
###### Parameters ######
# path to the current directory
pathToCurrentDir = path.dirname(__file__)
# path to the JSON option file
pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json")
# man page section
manSection = 1
# title (center header)
titlePage = "FASTFETCH"
# date (center footer)
# format : "Month (abbreviation) Day Year"
todayDate = datetime.fromtimestamp(
int(environ.get("SOURCE_DATE_EPOCH", time())),
tz=timezone.utc,
).strftime("%b %d %Y")
# file to fastfetch version (left footer)
pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt")
###### Sections Text ######
# text displayed in the "NAME" section
nameSection = r"fastfetch \- A fast and feature-rich system information tool similar to neofetch"
# text displayed in the "DESCRIPTION" section
descriptionSection = r"""
Fastfetch is a tool for displaying system information in a visually appealing way. Written primarily in C, it focuses on performance and customizability while providing functionality similar to neofetch.
It supports Linux, Android, FreeBSD, macOS, and Windows 7 or newer.
"""
# text displayed at the beginning of the "OPTIONS" section
optionSection = r"""
Options are parsed in a case-insensitive manner. For example, \fB--logo-type\fR and \fB--LOGO-TYPE\fR are treated identically.
Arguments in square brackets are optional. Optional boolean arguments default to 'true' when specified without a value.
For more detailed information about a specific option, use:
\fBfastfetch -h <option_name_without_dashes>\fR
Any combination of options can be made permanent by generating a configuration file:
\fBfastfetch <options> --gen-config\fR
"""
# text displayed in the "CONFIGURATION"
configurationSection = f"""
.SS Fetch Structure
The structure defines which modules to display and in what order. It consists of module names separated by colons (:).
For example: {startBold}title:separator:os:kernel:uptime{endBold}
To list all available modules, use {startBold}--list-modules{endBold}
.SS Config Files
Fastfetch uses JSONC (JSON with Comments) for configuration files. These files must have the .jsonc extension.
You can generate a default config file using {startBold}--gen-config{endBold}. By default, the config file is saved at {startBold}~/.config/fastfetch/config.jsonc{endBold}.
The configuration/preset files are searched in the following locations (in order):
{startBold}1.{endBold} Relative to the current working directory
{startBold}2.{endBold} Relative to ~/.local/share/fastfetch/presets/
{startBold}3.{endBold} Relative to /usr/share/fastfetch/presets/
For detailed information on logo options, module configuration, and formatting, visit:
{startBold}https://github.com/fastfetch-cli/fastfetch/wiki/Configuration{endBold}
Fastfetch provides several built-in presets. List them with {startBold}--list-presets{endBold}.
.SS JSON Schema
A JSON schema is available for editor intelligence when editing the configuration file. Add the following line at the beginning of your config file:
{startBold}"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"{endBold}
"""
# text displayed in the "EXAMPLE" section
exampleSection = f"""
.SS Basic Usage
{startBold}fastfetch{endBold}
.SS Use a specific logo
{startBold}fastfetch --logo arch{endBold}
.SS Custom structure
{startBold}fastfetch --structure title:os:kernel:uptime:memory{endBold}
.SS Generate a config file
{startBold}fastfetch --gen-config{endBold}
.SS Use a preset
{startBold}fastfetch --config neofetch{endBold}
.SS Config File Example
.nf
// ~/.config/fastfetch/config.jsonc
{{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {{
"type": "auto",
"source": "arch"
}},
"display": {{
"separator": ": ",
"color": {{
"keys": "blue",
"title": "red"
}},
"key": {{
"width": 12
}}
}},
"modules": [
"title",
"separator",
"os",
"kernel",
"uptime",
{{
"type": "memory",
"format": "{{used}}/{{total}} ({{used_percent}}%)"
}}
]
}}
.fi
"""
# text displayed in the "BUGS" section
bugSection = "Please report bugs to: https://github.com/fastfetch-cli/fastfetch/issues"
# text displayed in the "AUTHORS" section
authorsSection = "Fastfetch is developed by a team of contributors on GitHub.\nVisit https://github.com/fastfetch-cli/fastfetch for more information."
###### Argument decoration ######
### optional arguments tags ###
# if an optional argument is displayed as [?optArg] (with "optArg" underlined)
# this value should be f"[?{startUnderline}"
startOptionalArgument = f"[{startUnderline}"
# if an optional argument is displayed as [?optArg] (with "optArg underlined")
# this value should be f"{endUnderline}]"
endOptionalArgument = f"{endUnderline}]"
### mandatory arguments tags ###
startMandatoryArgument = f"{startUnderline}"
endMandatoryArgument = f"{endUnderline}"
def main():
# importing the JSON file
with open(pathToHelpFile, 'r') as jsonFile:
helpFileData = load(jsonFile) # json.load
######## Start printing the generated .1 file ########
###### header, footer & config #####
print(f".TH FASTFETCH {manSection} ", end=" ")
print(f"\"{todayDate}\"", end=" ")
# version number
with open(pathToVersionFile, 'r') as versionFile:
# research version number in file with regex
for line in versionFile:
researchVersion = search(r"^\s*VERSION (\d+\.\d+\.\d+)$", line)
if (researchVersion):
print(f"\"Fastfetch {researchVersion.group(1)}\"", end=" ")
break
print(f"\"{titlePage}\"")
###### Name ######
print(".SH NAME")
print(nameSection)
##### Synopsis ######
print(".SH SYNOPSIS")
print(".B fastfetch")
print(f"[{startUnderline}OPTIONS{endUnderline}...]")
###### Description ######
print(".SH DESCRIPTION")
print(descriptionSection)
###### Configuration ######
print(".SH CONFIGURATION")
print(configurationSection)
###### Options ######
print(".SH OPTIONS")
print(optionSection)
print()
# loop through every options sections
for key, value in helpFileData.items():
# print new subsection
print(f".SS {key}")
# loop through every option in a section
for option in value:
# list of existing keys for this option
keyList = option.keys()
# start a new "option" entry
print(".TP")
print(startBold, end="")
# short option (-opt)
if "short" in keyList:
print(fr"\-{ option['short'] }", end="")
# if also have a long option, print a comma
if "long" in keyList:
print(", ", end="")
# long option (--option)
if "long" in keyList:
print(fr"\-\-{ option['long'] }", end="")
print(endBold, end=" ")
# arguments
if "arg" in keyList:
# if argument is optional, print "[arg]"
if "optional" in option["arg"].keys() and option["arg"]["optional"]:
print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="")
# if argument is mandatory, print "arg"
else:
print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="")
# description
print()
# If desc is a list, join with newlines and proper spacing
if isinstance(option['desc'], list):
desc_text = "\n ".join(option['desc'])
print(f" {desc_text}")
else:
print(f" {option['desc']}")
# Add remarks if available
if "remark" in keyList:
print()
if isinstance(option['remark'], list):
for remark in option['remark']:
print(f" {remark}")
else:
print(f" {option['remark']}")
print()
###### Examples ######
print(".SH EXAMPLES")
print(exampleSection)
###### See Also ######
print(".SH \"SEE ALSO\"")
print(".BR neofetch (1)")
###### Bugs ######
print(".SH BUGS")
print(bugSection)
###### Authors ######
print(".SH AUTHORS")
print(authorsSection)
if __name__ == "__main__":
main()
|