diff --git a/src/help.py b/src/help.py index 0b4d1a8..252926f 100644 --- a/src/help.py +++ b/src/help.py @@ -5,15 +5,12 @@ import argparse from collections import namedtuple import os import re -from typing import Any ##- '$(ansi_py)' -## -###- TODO: seperate parsing from printing -### -ansi: Any MaxLens = namedtuple("MaxLens", "goal msg") -# double dollar signs to prevent make escaping them +###- double dollar signs to prevent make escaping them -### pattern = re.compile( r"^## (?P.*?) \| (?P.*?)(?:\s?\| args: (?P.*?))?$$|^### (?P.*?)?(?:\s?\| args: (?P.*?))?$$" ) @@ -50,57 +47,63 @@ def parse_make(file): yield {k: v for k, v in match.groupdict().items() if v is not None} -def print_goal(goal, msg, max_goal_len, argstr): +def fmt_goal(goal, msg, max_goal_len, argstr): args = parseargs(argstr) goal_style = args.goal_style.strip() if args.goal_style else "$(GOAL_STYLE)" msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)" - print( + return ( ansi.style(f" {goal:>{max_goal_len}}", goal_style) + " $(HELP_SEP) " + ansi.style(msg, msg_style) ) -def print_rawmsg(msg, argstr, maxlens): +def fmt_rawmsg(msg, argstr, maxlens): args = parseargs(argstr) + lines = [] msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)" if not os.getenv("SHOW_HIDDEN") and args.hidden: - return + return [] if msg: if args.align == "sep": - print( + lines.append( f"{' '*(maxlens.goal+len('$(HELP_SEP)')+4)}{ansi.style(msg,msg_style)}" ) elif args.align == "center": - print(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}") + lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}") else: - print(f" {ansi.style(msg,msg_style)}") + lines.append(f" {ansi.style(msg,msg_style)}") if args.divider: - print( + lines.append( ansi.style( f" {'$(DIVIDER)'*(len('$(HELP_SEP)')+sum(maxlens)+2)}", "$(DIVIDER_STYLE)", ) ) if args.whitespace: - print() + lines.append("\n") + + return lines def print_help(): - print(f"""$(USAGE)""") + lines = [f"""$(USAGE)"""] items = list(parse_make(gen_makefile())) maxlens = MaxLens( *(max((len(item[x]) for item in items if x in item)) for x in ["goal", "msg"]) ) - for item in items: if "goal" in item: - print_goal(item["goal"], item["msg"], maxlens.goal, item.get("msgargs", "")) + lines.append( + fmt_goal( + item["goal"], item["msg"], maxlens.goal, item.get("msgargs", "") + ) + ) if "rawmsg" in item: - print_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens) - - print(f"""$(EPILOG)""") + lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens)) + lines.append(f"""$(EPILOG)""") + print("\n".join(lines)) print_help() diff --git a/task.mk b/task.mk index cdc5a41..a988264 100644 --- a/task.mk +++ b/task.mk @@ -1,7 +1,7 @@ # }> [github.com/daylinmorgan/task.mk] <{ # # Copyright (c) 2022 Daylin Morgan # MIT License -# version: v22.9.14-12-g5a95a14-dev +# version: v22.9.14-13-gd2a239d-dev # # task.mk should be included at the bottom of your Makefile with `-include .task.mk` # See below for the standard configuration options that should be set prior to including this file. @@ -58,7 +58,9 @@ create_string = $(subst $(\n),\n,$(call escape_shellstring,$(call escape_printf, printline = printf -- "<----------------------------------->\n" ifdef DEBUG define _debug_runner -@printf "$(1) Script:\n";$(printline);printf "$(call create_string,$(3))\n";$(printline) +@printf "$(1) Script:\n";$(printline); +@printf "$(call create_string,$(3))\n" | cat -n +@$(printline) @printf "$(call create_string,$(3))" | $(2) endef py = $(call _debug_runner,Python,python3,$($(1))) @@ -74,11 +76,8 @@ import argparse from collections import namedtuple import os import re -from typing import Any $(ansi_py) -ansi: Any MaxLens = namedtuple("MaxLens", "goal msg") -# double dollar signs to prevent make escaping them pattern = re.compile( r"^## (?P.*?) \| (?P.*?)(?:\s?\| args: (?P.*?))?$$|^### (?P.*?)?(?:\s?\| args: (?P.*?))?$$" ) @@ -107,50 +106,57 @@ def parse_make(file): pass else: yield {k: v for k, v in match.groupdict().items() if v is not None} -def print_goal(goal, msg, max_goal_len, argstr): +def fmt_goal(goal, msg, max_goal_len, argstr): args = parseargs(argstr) goal_style = args.goal_style.strip() if args.goal_style else "$(GOAL_STYLE)" msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)" - print( + return ( ansi.style(f" {goal:>{max_goal_len}}", goal_style) + " $(HELP_SEP) " + ansi.style(msg, msg_style) ) -def print_rawmsg(msg, argstr, maxlens): +def fmt_rawmsg(msg, argstr, maxlens): args = parseargs(argstr) + lines = [] msg_style = args.msg_style.strip() if args.msg_style else "$(MSG_STYLE)" if not os.getenv("SHOW_HIDDEN") and args.hidden: - return + return [] if msg: if args.align == "sep": - print( + lines.append( f"{' '*(maxlens.goal+len('$(HELP_SEP)')+4)}{ansi.style(msg,msg_style)}" ) elif args.align == "center": - print(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}") + lines.append(f" {ansi.style(msg.center(sum(maxlens)),msg_style)}") else: - print(f" {ansi.style(msg,msg_style)}") + lines.append(f" {ansi.style(msg,msg_style)}") if args.divider: - print( + lines.append( ansi.style( f" {'$(DIVIDER)'*(len('$(HELP_SEP)')+sum(maxlens)+2)}", "$(DIVIDER_STYLE)", ) ) if args.whitespace: - print() + lines.append("\n") + return lines def print_help(): - print(f"""$(USAGE)""") + lines = [f"""$(USAGE)"""] items = list(parse_make(gen_makefile())) maxlens = MaxLens( *(max((len(item[x]) for item in items if x in item)) for x in ["goal", "msg"]) ) for item in items: if "goal" in item: - print_goal(item["goal"], item["msg"], maxlens.goal, item.get("msgargs", "")) + lines.append( + fmt_goal( + item["goal"], item["msg"], maxlens.goal, item.get("msgargs", "") + ) + ) if "rawmsg" in item: - print_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens) - print(f"""$(EPILOG)""") + lines.extend(fmt_rawmsg(item["rawmsg"], item.get("rawargs", ""), maxlens)) + lines.append(f"""$(EPILOG)""") + print("\n".join(lines)) print_help() endef define ansi_py