diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4e0f5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# ignore ALL files from the dist directory +dist/ +*.egg-info \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a5fab4 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ + +Process a Markdown file, execute commands within + +and print file contents with executed commands' output. + + + +## Installation + + + +The script is available on `PyPI`: + + + +``` +pip install markdown-command + +``` + + + +## Usage +``` + +markdown-command [options] FILE + + + +The pattern for commands to be executed is: + +[$ command --with-options -and arguments] + + + +Options: + +--help Display this message. + +--version Display version information. + +``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5750b88 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "markdown_command" +version = "0.9" +authors = [ + { name="Michal Moroz", email="michal@makimo.pl" }, + { name="Wojciech Mielczarek", email="wojciech.mielczarek@makimo.pl" }, +] +description = "Process a Markdown file, execute commands within and print file contents with executed commands' output." +readme = "README.md" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +dependencies = [ + 'docopt == 0.6.2', +] + +[project.urls] +"Homepage" = "https://github.com/makimo/markdown-command" +"Bug Tracker" = "https://github.com/makimo/markdown-command/issues" + +[project.scripts] +markdown-command = "markdown_command:main" \ No newline at end of file diff --git a/src/markdown_command.py b/src/markdown_command.py new file mode 100644 index 0000000..3b609ac --- /dev/null +++ b/src/markdown_command.py @@ -0,0 +1,77 @@ +""" +Process a Markdown file, execute commands within +and print file contents with executed commands' output. + +Usage: + markdown-command [options] FILE + +The pattern for commands to be executed is: + [$ command --with-options -and arguments] + +Options: + --help Display this message. + --version Display version information. +""" + +VERSION = '0.9' + + +import sys +import re + +import shutil + +import subprocess +from multiprocessing import Pool + +from docopt import docopt + +import shlex + + +pattern = re.compile(r'^\s*\[\$\s*([^\]]+)\]\s*$') + + +def run_cmd(command_string): + return subprocess.check_output( + shlex.split(command_string) + ).decode('utf-8') + + +def concurrently_map_to_dict(f, keys): + p = Pool() + results = p.map(f, keys) + p.close() + + return dict(zip(keys, results)) + + +def main(): + arguments = docopt(__doc__, version=VERSION) + + file = arguments['FILE'] + + with open(file, 'r') as f: + to_process = [] + + for line in f: + m = pattern.match(line) + + if not m: + continue + + to_process.append(m.group(1)) + + items = concurrently_map_to_dict(run_cmd, to_process) + + f.seek(0) + + for line in f: + m = pattern.match(line) + + if not m: + sys.stdout.write(line) + continue + + sys.stdout.write(items[m.group(1)]) + diff --git a/src/markdown_command/__init__.py b/src/markdown_command/__init__.py new file mode 100644 index 0000000..e69de29