codekingpro/portable-devtools
115k
1#!/usr/bin/env python2"""3CLI interface to markdown-it-py4 5Parse one or more markdown files, convert each to HTML, and print to stdout.6"""7 8from __future__ import annotations9 10import argparse11from collections.abc import Iterable, Sequence12import sys13 14from markdown_it import __version__15from markdown_it.main import MarkdownIt16 17version_str = f"markdown-it-py [version {__version__}]"18 19 20def main(args: Sequence[str] | None = None) -> int:21 namespace = parse_args(args)22 if namespace.filenames:23 convert(namespace.filenames)24 elif namespace.stdin:25 convert_stdin()26 else:27 interactive()28 return 029 30 31def convert(filenames: Iterable[str]) -> None:32 for filename in filenames:33 convert_file(filename)34 35 36def convert_stdin() -> None:37 """38 Parse a Markdown file and dump the output to stdout.39 """40 try:41 rendered = MarkdownIt().render(sys.stdin.read())42 print(rendered, end="")43 except OSError:44 sys.stderr.write("Cannot parse Markdown from the standard input.\n")45 sys.exit(1)46 47 48def convert_file(filename: str) -> None:49 """50 Parse a Markdown file and dump the output to stdout.51 """52 try:53 with open(filename, encoding="utf8", errors="ignore") as fin:54 rendered = MarkdownIt().render(fin.read())55 print(rendered, end="")56 except OSError:57 sys.stderr.write(f'Cannot open file "{filename}".\n')58 sys.exit(1)59 60 61def interactive() -> None:62 """63 Parse user input, dump to stdout, rinse and repeat.64 Python REPL style.65 """66 print_heading()67 contents = []68 more = False69 while True:70 try:71 prompt, more = ("... ", True) if more else (">>> ", True)72 contents.append(input(prompt) + "\n")73 except EOFError:74 print("\n" + MarkdownIt().render("\n".join(contents)), end="")75 more = False76 contents = []77 except KeyboardInterrupt:78 print("\nExiting.")79 break80 81 82def parse_args(args: Sequence[str] | None) -> argparse.Namespace:83 """Parse input CLI arguments."""84 parser = argparse.ArgumentParser(85 description="Parse one or more markdown files, "86 "convert each to HTML, and print to stdout",87 # NOTE: Remember to update README.md w/ the output of `markdown-it -h`88 epilog=(89 f"""90Interactive:91 92 $ markdown-it93 markdown-it-py [version {__version__}] (interactive)94 Type Ctrl-D to complete input, or Ctrl-C to exit.95 >>> # Example96 ... > markdown *input*97 ...98 <h1>Example</h1>99 <blockquote>100 <p>markdown <em>input</em></p>101 </blockquote>102 103Batch:104 105 $ markdown-it README.md README.footer.md > index.html106"""107 ),108 formatter_class=argparse.RawDescriptionHelpFormatter,109 )110 parser.add_argument("-v", "--version", action="version", version=version_str)111 parser.add_argument(112 "--stdin", action="store_true", help="read Markdown from standard input"113 )114 parser.add_argument(115 "filenames", nargs="*", help="specify an optional list of files to convert"116 )117 return parser.parse_args(args)118 119 120def print_heading() -> None:121 print(f"{version_str} (interactive)")122 print("Type Ctrl-D to complete input, or Ctrl-C to exit.")123 124 125if __name__ == "__main__":126 exit_code = main(sys.argv[1:])127 sys.exit(exit_code)128 