2024-11-12 20:13:13 -05:00
#!/usr/bin/env python3
2024-11-13 10:09:36 +08:00
2024-11-12 20:13:13 -05:00
"""
2025-04-04 18:15:54 +08:00
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
2024-11-12 20:13:13 -05:00
"""
from json import load
2024-11-23 23:22:57 -03:00
from datetime import datetime , timezone
2024-11-15 00:50:47 +00:00
from time import time
2024-11-12 20:13:13 -05:00
from re import search
2024-11-15 00:50:47 +00:00
from os import environ , path
2024-11-12 20:13:13 -05:00
###### Text Decorations Tags ######
2024-11-13 10:09:36 +08:00
startUnderline = r "\fI" # start underline text tag
endUnderline = r "\fR" # end underline text tag
2024-11-12 20:13:13 -05:00
2024-11-13 10:09:36 +08:00
startBold = r "\fB" # start bold text tag
endBold = r "\fR" # end bold text tag
2024-11-12 20:13:13 -05:00
###### Parameters ######
2024-11-13 10:09:36 +08:00
# path to the current directory
pathToCurrentDir = path . dirname ( __file__ )
2024-11-12 20:13:13 -05:00
# path to the JSON option file
2024-11-13 10:09:36 +08:00
pathToHelpFile = path . join ( pathToCurrentDir , "../src/data/help.json" )
2024-11-12 20:13:13 -05:00
# man page section
manSection = 1
# title (center header)
2025-04-04 18:15:54 +08:00
titlePage = "FASTFETCH"
2024-11-12 20:13:13 -05:00
# date (center footer)
2024-11-15 00:50:47 +00:00
# format : "Month (abbreviation) Day Year"
2024-11-23 23:22:57 -03:00
todayDate = datetime . fromtimestamp (
int ( environ . get ( "SOURCE_DATE_EPOCH" , time ())),
tz = timezone . utc ,
) . strftime ( "%b %d %Y" )
2024-11-12 20:13:13 -05:00
# file to fastfetch version (left footer)
2024-11-13 10:09:36 +08:00
pathToVersionFile = path . join ( pathToCurrentDir , "../CMakeLists.txt" )
2024-11-12 20:13:13 -05:00
###### Sections Text ######
# text displayed in the "NAME" section
2025-04-04 18:15:54 +08:00
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.
"""
2024-11-12 20:13:13 -05:00
# text displayed at the beginning of the "OPTIONS" section
2024-11-13 10:09:36 +08:00
optionSection = r """
2025-04-04 18:15:54 +08:00
Options are parsed in a case-insensitive manner. For example, \fB--logo-type\fR and \fB--LOGO-TYPE\fR are treated identically.
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
Arguments in square brackets are optional. Optional boolean arguments default to 'true' when specified without a value.
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
For more detailed information about a specific option, use:
\fBfastfetch -h <option_name_without_dashes>\fR
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
Any combination of options can be made permanent by generating a configuration file:
\fBfastfetch <options> --gen-config\fR
2024-11-13 10:09:36 +08:00
"""
2024-11-12 20:13:13 -05:00
# text displayed in the "CONFIGURATION"
2024-11-13 10:09:36 +08:00
configurationSection = f """
.SS Fetch Structure
2025-04-04 18:15:54 +08:00
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 }
2024-11-13 10:09:36 +08:00
.SS Config Files
2025-04-04 18:15:54 +08:00
Fastfetch uses JSONC (JSON with Comments) for configuration files. These files must have the .jsonc extension.
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
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 } .
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
The configuration/preset files are searched in the following locations (in order):
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
{ startBold } 1. { endBold } Relative to the current working directory
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
{ startBold } 2. { endBold } Relative to ~/.local/share/fastfetch/presets/
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
{ startBold } 3. { endBold } Relative to /usr/share/fastfetch/presets/
2024-11-13 10:09:36 +08:00
2025-04-04 18:15:54 +08:00
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 }
2024-11-13 10:09:36 +08:00
"""
2024-11-12 20:13:13 -05:00
# text displayed in the "EXAMPLE" section
2025-04-04 18:15:54 +08:00
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
2024-11-13 10:09:36 +08:00
.nf
// ~/.config/fastfetch/config.jsonc
2025-04-04 18:15:54 +08:00
{{
2024-11-13 10:09:36 +08:00
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
2025-04-04 18:15:54 +08:00
"logo": {{
"type": "auto",
"source": "arch"
}} ,
"display": {{
"separator": ": ",
"color": {{
"keys": "blue",
"title": "red"
}} ,
"key": {{
"width": 12
}}
}} ,
2024-11-13 10:09:36 +08:00
"modules": [
"title",
"separator",
2025-04-04 18:15:54 +08:00
"os",
"kernel",
"uptime",
{{
"type": "memory",
"format": " {{ used }} / {{ total }} ( {{ used_percent }} %)"
}}
2024-11-13 10:09:36 +08:00
]
2025-04-04 18:15:54 +08:00
}}
2024-11-13 10:09:36 +08:00
.fi
"""
2024-11-12 20:13:13 -05:00
# text displayed in the "BUGS" section
2025-04-04 18:15:54 +08:00
bugSection = "Please report bugs to: https://github.com/fastfetch-cli/fastfetch/issues"
2024-11-12 20:13:13 -05:00
2025-04-04 18:15:54 +08:00
# text displayed in the "AUTHORS" section
authorsSection = "Fastfetch is developed by a team of contributors on GitHub. \n Visit https://github.com/fastfetch-cli/fastfetch for more information."
2024-11-12 20:13:13 -05:00
###### Argument decoration ######
### optional arguments tags ###
# if an optional argument is displayed as [?optArg] (with "optArg" underlined)
# this value should be f"[?{startUnderline}"
2025-04-04 18:15:54 +08:00
startOptionalArgument = f "[ { startUnderline } "
2024-11-12 20:13:13 -05:00
# if an optional argument is displayed as [?optArg] (with "optArg underlined")
# this value should be f"{endUnderline}]"
2024-11-13 10:09:36 +08:00
endOptionalArgument = f " { endUnderline } ]"
2024-11-12 20:13:13 -05:00
### mandatory arguments tags ###
2024-11-13 10:09:36 +08:00
startMandatoryArgument = f " { startUnderline } "
2024-11-12 20:13:13 -05:00
endMandatoryArgument = f " { endUnderline } "
2024-11-13 10:09:36 +08:00
def main ():
2024-11-12 20:13:13 -05:00
# importing the JSON file
2024-11-13 10:09:36 +08:00
with open ( pathToHelpFile , 'r' ) as jsonFile :
helpFileData = load ( jsonFile ) # json.load
2024-11-12 20:13:13 -05:00
######## Start printing the generated .1 file ########
###### header, footer & config #####
2024-11-13 10:09:36 +08:00
print ( f ".TH FASTFETCH { manSection } " , end = " " )
2024-11-12 20:13:13 -05:00
print ( f " \" { todayDate } \" " , end = " " )
# version number
2024-11-13 10:09:36 +08:00
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 ):
2025-04-04 18:15:54 +08:00
print ( f " \" Fastfetch { researchVersion . group ( 1 ) } \" " , end = " " )
2024-11-13 10:09:36 +08:00
break
2024-11-12 20:13:13 -05:00
print ( f " \" { titlePage } \" " )
###### Name ######
print ( ".SH NAME" )
print ( nameSection )
##### Synopsis ######
print ( ".SH SYNOPSIS" )
print ( ".B fastfetch" )
2025-04-04 18:15:54 +08:00
print ( f "[ { startUnderline } OPTIONS { endUnderline } ...]" )
2024-11-12 20:13:13 -05:00
2025-04-04 18:15:54 +08:00
###### Description ######
2024-11-12 20:13:13 -05:00
2025-04-04 18:15:54 +08:00
print ( ".SH DESCRIPTION" )
print ( descriptionSection )
2024-11-12 20:13:13 -05:00
###### 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
2025-04-04 18:15:54 +08:00
print ( f ".SS { key } " )
2024-11-12 20:13:13 -05:00
# 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 :
2024-11-13 10:09:36 +08:00
print ( fr "\- { option [ 'short' ] } " , end = "" )
2024-11-12 20:13:13 -05:00
# if also have a long option, print a comma
if "long" in keyList :
print ( ", " , end = "" )
# long option (--option)
if "long" in keyList :
2024-11-13 10:09:36 +08:00
print ( fr "\-\- { option [ 'long' ] } " , end = "" )
2024-11-12 20:13:13 -05:00
print ( endBold , end = " " )
2024-11-13 10:09:36 +08:00
2024-11-12 20:13:13 -05:00
# 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 = "" )
2024-11-13 10:09:36 +08:00
2024-11-12 20:13:13 -05:00
# description
2025-04-04 18:15:54 +08:00
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 ()
2024-11-13 10:09:36 +08:00
2024-11-12 20:13:13 -05:00
###### Examples ######
print ( ".SH EXAMPLES" )
print ( exampleSection )
2025-04-04 18:15:54 +08:00
###### See Also ######
print ( ".SH \" SEE ALSO \" " )
print ( ".BR neofetch (1)" )
2024-11-12 20:13:13 -05:00
###### Bugs ######
print ( ".SH BUGS" )
print ( bugSection )
2025-04-04 18:15:54 +08:00
###### Authors ######
print ( ".SH AUTHORS" )
print ( authorsSection )
2024-11-12 20:13:13 -05:00
if __name__ == "__main__" :
2024-11-13 10:09:36 +08:00
main ()