text: #!/usr/bin/python3
  #
  # Python script that regenerates the README.md from the embedded template. Uses
  # ./generate_table.awk to regenerate the ASCII tables from the various *.txt
  # files.
  
  from subprocess import check_output
  
  attiny_results = check_output(
      "./generate_table.awk < attiny.txt", shell=True, text=True)
  nano_results = check_output(
      "./generate_table.awk < nano.txt", shell=True, text=True)
  micro_results = check_output(
      "./generate_table.awk < micro.txt", shell=True, text=True)
  samd_results = check_output(
      "./generate_table.awk < samd.txt", shell=True, text=True)
  stm32_results = check_output(
      "./generate_table.awk < stm32.txt", shell=True, text=True)
  esp8266_results = check_output(
      "./generate_table.awk < esp8266.txt", shell=True, text=True)
  esp32_results = check_output(
      "./generate_table.awk < esp32.txt", shell=True, text=True)
  teensy32_results = check_output(
      "./generate_table.awk < teensy32.txt", shell=True, text=True)
  
  print(f"""\
  # Memory Benchmark
  
  The `MemoryBenchmark.ino` collects the amount of flash and static memory
  consumed by different implementations in the AceSPI library.
  
  It compiles various code snippets which are controlled by the `FEATURE` macro
  flag. The `collect.sh` edits this `FEATURE` flag programmatically, then runs the
  Arduino IDE compiler on the program, and extracts the flash and static memory
  usage into a text file (e.g. `nano.txt`).
  
  The numbers shown below should be considered to be rough estimates. It is often
  difficult to separate out the code size of the library from the overhead imposed
  by the runtime environment of the processor. For example, it often seems like
  the ESP8266 allocates flash memory in blocks of a certain quantity, so the
  calculated flash size can jump around in unexpected ways.
  
  **Version**: AceSPI v0.3
  
  **DO NOT EDIT**: This file was auto-generated using `make README.md`.
  
  ## How to Generate
  
  This requires the [AUniter](https://github.com/bxparks/AUniter) script
  to execute the Arduino IDE programmatically.
  
  The `Makefile` has rules for several microcontrollers:
  
  ```
  $ make benchmarks
  ```
  produces the following files:
  
  ```
  attiny.txt
  nano.txt
  micro.txt
  samd.txt
  stm32.txt
  esp8266.txt
  esp32.txt
  teensy32.txt
  ```
  
  The `generate_table.awk` program reads one of `*.txt` files and prints out an
  ASCII table that can be directly embedded into this README.md file. For example
  the following command produces the table in the Nano section below:
  
  ```
  $ ./generate_table.awk < nano.txt
  ```
  
  Fortunately, we no longer need to run `generate_table.awk` for each `*.txt`
  file. The process has been automated using the `generate_readme.py` script which
  will be invoked by the following command:
  ```
  $ make README.md
  ```
  
  ## Library Size Changes
  
  **v0.2**
  
  * Initial MemoryBenchmark using the old v0.3 implementation from 2018,
  before substantional refactoring in 2021.
  
  ## Results
  
  The following shows the flash and static memory sizes of the `MemoryBenchmark`
  program for various `LedModule` configurations and various Writer classes.
  
  * `SimpleSpiInterface`
  * `SimpleSpiFastInterface`
  * `HardSpiInterface`
  * `HardSpiFastInterface`
  
  ### ATtiny85
  
  * 8MHz ATtiny85
  * Arduino IDE 1.8.13
  * SpenceKonde/ATTinyCore 1.5.2
  
  ```
  {attiny_results}
  ```
  
  ### Arduino Nano
  
  * 16MHz ATmega328P
  * Arduino IDE 1.8.13
  * Arduino AVR Boards 1.8.3
  
  ```
  {nano_results}
  ```
  
  ### Sparkfun Pro Micro
  
  * 16 MHz ATmega32U4
  * Arduino IDE 1.8.13
  * SparkFun AVR Boards 1.1.13
  
  ```
  {micro_results}
  ```
  
  ### SAMD21 M0 Mini
  
  * 48 MHz ARM Cortex-M0+
  * Arduino IDE 1.8.13
  * Sparkfun SAMD Core 1.8.3
  
  ```
  {samd_results}
  ```
  
  ### STM32 Blue Pill
  
  * STM32F103C8, 72 MHz ARM Cortex-M3
  * Arduino IDE 1.8.13
  * STM32duino 2.0.0
  
  ```
  {stm32_results}
  ```
  
  ### ESP8266
  
  * NodeMCU 1.0, 80MHz ESP8266
  * Arduino IDE 1.8.13
  * ESP8266 Boards 2.7.4
  
  ```
  {esp8266_results}
  ```
  
  ### ESP32
  
  * ESP32-01 Dev Board, 240 MHz Tensilica LX6
  * Arduino IDE 1.8.13
  * ESP32 Boards 1.0.6
  
  ```
  {esp32_results}
  ```
  
  ### Teensy 3.2
  
  * 96 MHz ARM Cortex-M4
  * Arduino IDE 1.8.13
  * Teensyduino 1.53
  * Compiler options: "Faster"
  
  ```
  {teensy32_results}
  ```
  """)
  