from json import load
from datetime import datetime, timezone
from time import time
from re import search
from os import environ, path
startUnderline = r"\fI" endUnderline = r"\fR"
startBold = r"\fB" endBold = r"\fR"
pathToCurrentDir = path.dirname(__file__)
pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json")
manSection = 1
titlePage = "FASTFETCH"
todayDate = datetime.fromtimestamp(
int(environ.get("SOURCE_DATE_EPOCH", time())),
tz=timezone.utc,
).strftime("%b %d %Y")
pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt")
nameSection = r"fastfetch \- A fast and feature-rich system information tool similar to neofetch"
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.
"""
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
"""
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}
"""
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
"""
bugSection = "Please report bugs to: https://github.com/fastfetch-cli/fastfetch/issues"
authorsSection = "Fastfetch is developed by a team of contributors on GitHub.\nVisit https://github.com/fastfetch-cli/fastfetch for more information."
startOptionalArgument = f"[{startUnderline}"
endOptionalArgument = f"{endUnderline}]"
startMandatoryArgument = f"{startUnderline}"
endMandatoryArgument = f"{endUnderline}"
def main():
with open(pathToHelpFile, 'r') as jsonFile:
helpFileData = load(jsonFile)
print(f".TH FASTFETCH {manSection} ", end=" ")
print(f"\"{todayDate}\"", end=" ")
with open(pathToVersionFile, 'r') as versionFile:
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}\"")
print(".SH NAME")
print(nameSection)
print(".SH SYNOPSIS")
print(".B fastfetch")
print(f"[{startUnderline}OPTIONS{endUnderline}...]")
print(".SH DESCRIPTION")
print(descriptionSection)
print(".SH CONFIGURATION")
print(configurationSection)
print(".SH OPTIONS")
print(optionSection)
print()
for key, value in helpFileData.items():
print(f".SS {key}")
for option in value:
keyList = option.keys()
print(".TP")
print(startBold, end="")
if "short" in keyList:
print(fr"\-{ option['short'] }", end="")
if "long" in keyList:
print(", ", end="")
if "long" in keyList:
print(fr"\-\-{ option['long'] }", end="")
print(endBold, end=" ")
if "arg" in keyList:
if "optional" in option["arg"].keys() and option["arg"]["optional"]:
print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="")
else:
print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="")
print()
if isinstance(option['desc'], list):
desc_text = "\n ".join(option['desc'])
print(f" {desc_text}")
else:
print(f" {option['desc']}")
if "remark" in keyList:
print()
if isinstance(option['remark'], list):
for remark in option['remark']:
print(f" {remark}")
else:
print(f" {option['remark']}")
print()
print(".SH EXAMPLES")
print(exampleSection)
print(".SH \"SEE ALSO\"")
print(".BR neofetch (1)")
print(".SH BUGS")
print(bugSection)
print(".SH AUTHORS")
print(authorsSection)
if __name__ == "__main__":
main()