87 lines
3.4 KiB
Python
Executable File
87 lines
3.4 KiB
Python
Executable File
#!/usr/bin/python3
|
|
import os
|
|
import sys
|
|
from urllib.parse import urljoin, quote
|
|
|
|
def path_to_file_uri(path):
|
|
"""
|
|
Converts a file path to a file URI.
|
|
Handles absolute and relative paths.
|
|
"""
|
|
abs_path = os.path.abspath(path)
|
|
return urljoin("file://", quote(abs_path))
|
|
|
|
def is_binary_file(filepath, chunk_size=1024):
|
|
"""
|
|
Prüft, ob eine Datei binär ist, indem sie den Inhalt der Datei auf nicht-druckbare Zeichen untersucht.
|
|
"""
|
|
try:
|
|
with open(filepath, "rb") as file:
|
|
chunk = file.read(chunk_size)
|
|
if b"\0" in chunk: # Nullbyte ist ein typisches Zeichen für Binärdateien
|
|
return True
|
|
return False
|
|
except Exception as e:
|
|
print(f"Fehler beim Prüfen, ob Datei binär ist: {filepath}: {e}")
|
|
return True
|
|
|
|
def search_keywords_in_files(keywords):
|
|
if not keywords:
|
|
print("Bitte geben Sie mindestens ein Stichwort an.")
|
|
sys.exit(1)
|
|
|
|
# Allowed comment symbols
|
|
comment_symbols = {"//", "#", ";"}
|
|
|
|
for root, dirs, files in os.walk("."):
|
|
# Ausschließen bestimmter Verzeichnisse
|
|
dirs[:] = [d for d in dirs if d not in {".git", "build"}]
|
|
|
|
for file in files:
|
|
filepath = os.path.join(root, file)
|
|
|
|
# Überspringen von Binärdateien
|
|
if is_binary_file(filepath):
|
|
continue
|
|
|
|
try:
|
|
with open(filepath, "r", encoding="utf-8") as f:
|
|
lines = f.readlines()
|
|
|
|
for line_number, line in enumerate(lines, start=1):
|
|
stripped_line = line.lstrip() # Entfernt führende Leerzeichen
|
|
for symbol in comment_symbols:
|
|
if stripped_line.startswith(symbol):
|
|
# Entfernt das Kommentarzeichen und nachfolgende Leerzeichen
|
|
howtoMatch = stripped_line[len(symbol):].lstrip()
|
|
if howtoMatch.startswith(("HOWTO ", "HOWTO: ", "How to ")):
|
|
if all(keyword in howtoMatch.lower() for keyword in keywords):
|
|
|
|
# Titelzeile ohne Kommentarzeichen
|
|
print(howtoMatch.rstrip())
|
|
|
|
# Ausgabe nachfolgender Zeilen mit dem gleichen Kommentar-Präfix
|
|
for subsequent_line in lines[line_number:]:
|
|
subsequent_line = subsequent_line.lstrip()
|
|
if subsequent_line.startswith(symbol):
|
|
# Entfernt Kommentarzeichen aus Folgezeilen
|
|
print("\t" + subsequent_line[len(symbol):].strip())
|
|
else:
|
|
break
|
|
|
|
# Link mit Zeilennummer
|
|
print(f"--> {path_to_file_uri(filepath)}:{line_number}")
|
|
|
|
# Abstand zwischen Matches
|
|
print()
|
|
break
|
|
except Exception as e:
|
|
print(f"Fehler beim Lesen der Datei {filepath}: {e}")
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("Verwendung: bin/howto <Stichwort1> <Stichwort2> ...")
|
|
sys.exit(1)
|
|
|
|
search_keywords_in_files([arg.lower() for arg in sys.argv[1:]])
|