This is a demonstration of the demonic project, specifically by running editable code snippets from a markdown-converted document.
demonic was inspired by mdbook, which is a great Rust documentation project. In mdbook, you can edit and run Rust code right from the document (e.g. Hello World)! I really liked this feature, but wanted to be able to send input back to the running process.
demonic-web allows one to do this, and demonic-docs integrates it with html-ized markdown documents. Go ahead and play around and edit any of the code blocks below, and click on the āā¶ā button to run them!
C
#include <stdio.h>
int main(int argc, char** argv) {
fprintf(stderr, "%s", "Enter your name: ");
char name[100];
scanf("%s", name);
fprintf(stderr, "Hello %s!\n", name);
return 0;
}
C++
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main(int argc, char** argv) {
string name;
cout << "What is your name? ";
cin >> name;
cout << "Hello " << name << "!" << endl;
}
Go
package main
import (
"fmt"
"bufio"
"os"
"strings"
)
func main() {
fmt.Print("What is your name? ")
reader := bufio.NewReader(os.Stdin)
name,_ := reader.ReadString('\n')
name = strings.Replace(name, "\n", "", -1);
fmt.Printf("Hello %s!\n", name)
}
Java
import java.util.Scanner;
public class Hello {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("What is your name? ");
String name = reader.nextLine();
System.out.println("Hello " + name + "!");
reader.close();
}
}
JavaScript (Node.js)
const readline = require('readline');
const readline_interface = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
readline_interface.question('What is your name? ', name => {
console.log(`Hello ${name}!`);
readline_interface.close();
process.exit();
})
Python
def greet():
name = input('Enter your name: ')
print('Hello', name)
if __name__ == '__main__':
greet()
Racket
#lang racket
(define (greet)
(display "Enter your name: ")
(printf "Hello, ~a!\n"
(read-line (current-input-port) 'any)))
(greet)
Ruby
def greet()
print 'What is your name ? '
STDOUT.flush
name = gets
name = name.chomp
puts 'Hello ' + name + '!'
end
greet()
Rust
use std::io::stdin;
use std::io::stdout;
use std::io::Write;
fn greet() {
let mut name = String::new();
print!("What is your name? ");
let _ = stdout().flush();
stdin().read_line(&mut name)
.ok()
.expect("Error in reading stdin.");
if let Some('\n') = name.chars().next_back() {
name.pop();
}
println!("Hello {}!", name);
}
fn main() {
greet();
}
Shell
#!/bin/sh
greet() {
read -p "What is your name? " name
echo "Hello $name"
}
greet
Support and Roadmap
This project aims to allow unmodified markdown files to have editable and runnable code blocks. But there needs to be a way for users to tell which program blocks they want to run and which they donāt. Unfortunately, this requires a modification to the markdown files! In this instance, the following markdown code had a ā.norunā class addition, which tells demonic not to add a āā¶ā button to the code block.
{: .norun}
```python
print("Don't run me!")
```
print("Don't run me!")
Markdown files converted by Pandoc are the only supported format currently, but Iād like to add lots of others! Iād like to add the following features:
- Add more documentation. This is a documentation project at heart!
- Adding more languages! This should be forthcoming. Stay tuned!
- Being able to make code blocks ānon-runnableā by default.
- Compiling/running multiple files. This may include using the multiple buffer functionality of CodeMirror.
- Jekyll-converted markdown documents.
- Org-mode HTML-ized documents.
- Mdbook-converted markdown documents.
- Import/export ability.
- Being able to switch modes for each buffer. This should be made a little easier by CodeMirrorās ability to do just that.
- Having the option to run the code block converter from the command line i.e. not only at āruntimeā as it currently does).
- Having the option to choose between CodeMirror and Ace for the online editors.
- If you have any other suggestions, let me know at this issue reporter or by e-mail. Iām available at liam@liambeckman.com : )
Adding support requires playing around with the resulting DOM structure of each converter and file type, and being able to extract the language
and code
of each code block.