Package: readme_executor
README EXECUTORA tool for executing Python code blocks in Markdown documentation.Copyright 2022 Randall MorganIntroductionThis script reads Markdown documents, locating tagged Python code blocks,
executing them, and capturing their output. The output from the code block
is then inserted into a generated Markdown document.This script was developed to help ensure that code samples in Python project
documentation actually reflected the current version of the software.
Running this script as part of the CI/CD process will help you keep your docs
current with the latest software version. Note that this script does not parse
Python code to generate Markdown documentation. There are many good tools for
that already. The focus of this tool is solely to aid in maintaining code
samples in that documentation.UsageThis script is ran on an existing Markdown document template. The template is
a regular Markdown document containing specially tagged code blocks as described
below. In fact, this script was used to generate this readme you are reading now.
It was generated using the Markdown template file /doc_src/readme_template.md
found in the doc_src folder of this project. It is recommended that you read the
template file as well as this document to gain a full understanding before creating
your own Markdown template files for your projects.Since this document includes textual code snippets and actual tagged code blocks.
I have denoted the textual code snippets withRenderedand the tagged code
blocks that are parsed and executed withCode. This will aid in grokking the
Markdown template and demonstrates how the code blocks are displayed in the final
document.Running the script:If this script is invoked without specifying an input file, input will be taken from
standard input (stdin). If an output file is not specified, output will be sent to
standard out (stdout). A debug flag (-d) may be passed on the command line. When
provided, the script displays the code blocks it found and parsed. A force-overwrite
flag (-f) can also be specified and will cause the script to overwrite an existing
output file.Command-Line Options:usage: Examples:
----------------
	readme_executor.py                                                    # Input taken from stdin, output is stdout
	readme_executor.py -i doc_src/readme.md                               # Input file specified, output will be stdout
	readme_executor.py -i doc_src/classes.md -o docs/classes_doc.md       # Input and Output filename specified in command
	readme_executor.py -i doc_src/contrib.md -o docs/contributing.md -d   # Display all matched code blocks for debugging
	readme_executor.py -i doc_src/contrib.md -o docs/contributing.md -f   # Force existing output file to be overwritten.

options:
  -h, --help            show this help message and exit
  -i INFILE, --infile INFILE
                        The source markdown document
  -o OUTFILE, --outfile OUTFILE
                        The markdown file to be generated
  -d, --debug           Outputs the tagged code blocks found by the parser
                        This is helpful for debugging when results are not as
                        expected
  -f, --force           Force output to overwrite existing fileExample Invocations$ readme_executor.py                                                            # input will be taken from stdin, and output sent to stdout
$ readme_executor.py -i ./doc_src/readme_template.md                            # input file specified, output sent to stdout
$ readme_executor.py -i ./doc_src/readme_template.md -o ./docs/readme.md        # input and output files specified
$ readme_executor.py -i ./doc_src/readme_template.md -o ./docs/readme.md -d     # debug output
$ readme_executor.py -i ./doc_src/readme_template.md -o ./docs/readme.md -f     # force the script to overwrite an existing output fileTagging Code BlocksNon-Tagged Code blocksNon-tagged code blocks like this are not processed:print('Leave this alone')Tagged Code BlocksCode blocks containing directives will be processed. A directive is made up of three parts:* The delimiters: { and }.
* The language indicator: .python 
* The directive: capture, replace, exceptionPutting this all together a typical tagged code block would look like:''' { .python capture }

import math

x, y = 47, 96

print(f'Coords: {math.sin(x)}, {math.cos(y)}') 

'''Note that while triple single-quotes are shown here, triple back-ticks are required in the markdown file.Note that currently Python is the only programming language supported. But this may change in the future.CaptureThecapturedirective indicates that the standard output should be captured and inserted as a new code block below the code.Rendered''' { .python capture }
print('This output should be captured!')
print('This too')
'''Codeprint('This output should be captured!')
print('This too')Output:This output should be captured!
This tooReplaceThereplacedirective indicates that the code should be replaced by the output.This code...Rendered:''' { .python replace } 
print('A replace cell')
'''Gets replaced with:CodeA replace cellExceptionTheexceptiondirective indicates that the code should raise anException.
The traceback is then inserted instead of the standard output.
Theexceptiondirective is used with thecaptureandreplacedirectives.Rendered''' { .python capture exception }
# A cell that should raise a ValueError
int('x')
'''Code# A cell that should raise a ValueError
int('x')Output:invalid literal for int() with base 10: 'x'APIIf you wish to use readme_executor as a module in your own
document processor, the following text will help.## parse_text(md_in: str, debug=False) -> str

Accepts a `str` containing Markdown text, then finds the tagged code blocks
in the markdown, executes these code blocks and captures the output, which is
then embedded into the output markdown.

### Parameters

* md_in: str

  The input Markdown text string

* debug: bool

  default: False, if True outputs mathing tagged code blocks

### Returns

  str

  The compiled markdown string
  
  
## parse_file(src: str, dest: str, debug=False)

Takes a markdown file as input, executes any code blocks contained within,
captures the output and write the result to a new file.

* src: str
    The full path to the input file
* dest: str
    The full path for the output fileLicenseThis software is licensed under the GNU General Public License
version 2 or later. At the user's discretion. You are free to
use this script, and it's source code any way you like.WarantyThis software is provided without warranty of any kind! The user is
solely responsibility to determine the suitability of this software
for their own specific use case.