Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Markdown to Shell conversion
#!/usr/bin/php
<?php
/**
* Script to extract any Shell commands from a Markdown document
*
* It takes a Markdown stream (from STDIN) and only keeps the "```Shell"-blocks content.
* By adding a Shebang first, the ouput is directly executable.
*/
$shebang = '#!/bin/sh';
$emptyLinesAfterBlocks = 2;
$markdown = stream_get_contents(STDIN);
$markdown = preg_replace('/\r\n|\r|\n/', "\n", $markdown); // Deal with various EOL: make it all "\n"
preg_match_all('/^(?P<margin> *)```Shell$\n(?P<shell>.*)\n^ *```$/misU', $markdown, $matches);
fwrite(STDOUT, $shebang . PHP_EOL . PHP_EOL);
foreach ($matches['shell'] as $shellIndex => $shellBlockContent) {
$margin = strlen($matches['margin'][$shellIndex]);
if ($margin === 0) {
fwrite(STDOUT, $shellBlockContent . PHP_EOL);
} else {
foreach (explode("\n", $shellBlockContent) as $currentLine) {
fwrite(STDOUT, substr($currentLine, $margin) . PHP_EOL);
}
}
fwrite(STDOUT, str_repeat(PHP_EOL, $emptyLinesAfterBlocks));
}
#!/usr/bin/php
<?php
/**
* Script to convert a Markdown document to an executable shell file
*
* It takes a Markdown stream (from STDIN) and comment anything that is not a "```Shell"-block.
* By adding a Shebang first, the ouput is directly executable.
*/
$shebang = '#!/bin/sh';
$commentString = '# ';
$emptyLinesAroundBlocks = 2;
/**
* Tells if inside a Shell block or not and which left-margin it had in Markdown.
* bool(false) when not inside a Shell block, the width of the left-margin when inside one.
* @var boolean|int
*/
$marginBlockPadding = false;
fwrite(STDOUT, $shebang . PHP_EOL . PHP_EOL);
while (($line = fgets(STDIN)) !== false) {
$lineEolNormalized = preg_replace('/\r\n|\r|\n/', "\n", $line); // Deal with various EOL: make it all "\n"
if (
$marginBlockPadding !== false
&& preg_match('/^ *```$/iU', $lineEolNormalized) // Detects end of (Shell) block
) {
$marginBlockPadding = false;
fwrite(STDOUT, str_repeat(PHP_EOL, $emptyLinesAroundBlocks));
}
if ($marginBlockPadding === false) { // Outside of Shell block
$lineToPrint = $commentString . $lineEolNormalized;
if (preg_match('/^(?P<margin> *)```Shell$/iU', $lineEolNormalized, $matches)) { // Detects start of Shell block
$marginBlockPadding = strlen($matches['margin']); // Note the margin width
$lineToPrint .= str_repeat(PHP_EOL, $emptyLinesAroundBlocks);
}
} else { // Inside Shell block
$lineToPrint = substr($lineEolNormalized, $marginBlockPadding); // Remove the left-margin
}
fwrite(STDOUT, $lineToPrint);
}
if (!feof(STDIN)) {
fwrite(STDERR, 'Error: unexpected fgets() fail' . PHP_EOL);
}
# Create a Markdown to demo on:
cat > ./SomeDocument.md <<'EOT'
# Demo of markdown2shell.php and extract_shell_from_markdown.php
This document tells how to one can use `markdown2shell.php` (or `extract_shell_from_markdown.php`) to convert a
Markdown document into an executable of every Shell command it contains.
## Convert for future (re-)use
```Shell
cat SomeDocument.md | ./markdown2shell.php > SomeDocument.md.sh
# or:
cat SomeDocument.md | ./extract_shell_from_markdown.php > SomeDocument.sh
```
You can execute now your obtained shell file:
```Shell
sh SomeDocument{,.md}.sh
```
## Convert and execute on-the-fly (probably not a good idea)
```Shell
cat SomeDocument.md | ./markdown2shell.php | sh
# or:
cat SomeDocument.md | ./extract_shell_from_markdown.php | sh
```
EOT
# Convert it
cat SomeDocument.md | ./markdown2shell.php > SomeDocument.md.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.