docdown 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c2548137fcc0b4ebb025c13d5178d8d597ba644b
4
+ data.tar.gz: 1a5911b45cf51cab6d2c0b6f91fa51afe112a275
5
+ SHA512:
6
+ metadata.gz: 6ef2f77c978d5d01d0d4757f79c078b3a67eb2c796188e36aa91e670f83ae610ac63d5068d83d59182f33af4e04b64bf5594a1848bb77e118fe0c61710d77082
7
+ data.tar.gz: 558c52df2dd318be7a675c6018a41a31fc986eaea8bda4a8111454431e44d56ed02802cc799e166e09437e5ab274249c0a3f272ac68a82671a6cb93788ce1216
@@ -0,0 +1 @@
1
+ test/fixtures/project/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ heroku_docdown (0.0.1)
5
+ repl_runner
6
+ thor
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activesupport (4.0.0)
12
+ i18n (~> 0.6, >= 0.6.4)
13
+ minitest (~> 4.2)
14
+ multi_json (~> 1.3)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 0.3.37)
17
+ atomic (1.1.14)
18
+ i18n (0.6.5)
19
+ metaclass (0.0.1)
20
+ minitest (4.7.5)
21
+ mocha (0.14.0)
22
+ metaclass (~> 0.0.1)
23
+ multi_json (1.8.0)
24
+ rake (10.1.0)
25
+ repl_runner (0.0.2)
26
+ activesupport
27
+ thor (0.18.1)
28
+ thread_safe (0.1.3)
29
+ atomic
30
+ tzinfo (0.3.37)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ heroku_docdown!
37
+ mocha
38
+ rake
@@ -0,0 +1,126 @@
1
+ ## Docdown
2
+
3
+ ## What
4
+
5
+ Write your code/docs once, don't repeat yourself. Changes/updates to docs are guaranteed to match your project
6
+
7
+ ## Why
8
+
9
+ I wrote a Rails course, that required I build an app and write
10
+ documentation for building said app. Wouldn't it be cool if instead
11
+ while I write the documentation I could automate the building of my
12
+ app?
13
+
14
+ Totally! That's this, this is that thing.
15
+
16
+ Write docs that build software.
17
+
18
+ Why docs to code and not code to docs? Code is hard, cold and machine runnable. Docs are soft, consumed by people, and need high flexability. It's easier to explicitly tell the machine what code you want generated, then to go the other way.
19
+
20
+ ## Install
21
+
22
+ For now this software is distributed as a rubygem. Install it manually:
23
+
24
+ ```
25
+ $ gem install docdown
26
+ ```
27
+
28
+ or add it to your Gemfile:
29
+
30
+ ```
31
+ gem 'docdown`
32
+ ```
33
+
34
+ ## Use It
35
+
36
+ Run the docdown command on any makdown file
37
+
38
+ ```sh
39
+ $ docdown build my_file.md
40
+ ```
41
+
42
+ This will generate a project folder with your project in it, and a markdown README.md with the parsed output of the markdown docs.
43
+
44
+ ## Write it
45
+
46
+ Docdown uses github flavored markdown and the html-pipeline behind
47
+ the scenes. This means you write like normal but in your code sections
48
+ you can add special annotations that when run through docdown can
49
+ generate a project.
50
+
51
+ All docdown commands are prefixed with three colons `:::` and are inclosed in a code block a
52
+ command such as `$` which is an alias for `bash` commands like this:
53
+
54
+ ```
55
+ ::: $ git init .
56
+ ```
57
+
58
+ Nothing before the three colons matters. The space between the colons
59
+ and the command is optional.
60
+
61
+ If you don't want the command to output to your markdown document you
62
+ can add a minus symbol `-` to the end to prevent it from being
63
+ rendered.
64
+
65
+ ```
66
+ :::- $ git init .
67
+ ```
68
+
69
+ If you want the output of the actual command to be rendered to
70
+ the screen you can use an equal sign so that
71
+
72
+ ```
73
+ :::= $ ls
74
+ ```
75
+
76
+ Might generate an output something like this to your markdown doc:
77
+
78
+ ```
79
+ $ ls
80
+ Gemfile README.rdoc app config.ru doc log script tmp
81
+ Gemfile.lock Rakefile config db lib public test vendor
82
+ ```
83
+
84
+ That's how you manipulate the shell with docdown, let's take a look at manipulating code.
85
+
86
+
87
+ ## Files
88
+
89
+ Right now you can only write to files. Use the `write` keyword followed by a filename, on the next line(s) put the contents of the file
90
+
91
+ ```
92
+ ::: write config/routes.rb
93
+
94
+ Example::Application.routes.draw do
95
+ root :to => "pages#index"
96
+
97
+ namespace :users do
98
+ resources :after_signup
99
+ end
100
+ end
101
+ ```
102
+
103
+ If you wanted to change `users` to `products` you would write to the same file again.
104
+
105
+ ```
106
+ ::: write config/routes.rb
107
+ Example::Application.routes.draw do
108
+ root :to => "pages#index"
109
+
110
+ namespace :products do
111
+ resources :after_signup
112
+ end
113
+ end
114
+ ```
115
+
116
+ To delete files use bash `$` command.
117
+
118
+
119
+
120
+ ## TODO
121
+
122
+ - Debug output
123
+ - Fail and exit on non zero exit code
124
+ - Breakpoints?
125
+ - Bash commands with side effects (cd; pwd; on different lines should actually change working directory)
126
+ - Better line matching for backtrace
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'docdown'
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+
9
+ task :default => [:test]
10
+
11
+ test_task = Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ unless File.respond_to? :realpath
4
+ class File #:nodoc:
5
+ def self.realpath path
6
+ return realpath(File.readlink(path)) if symlink?(path)
7
+ path
8
+ end
9
+ end
10
+ end
11
+ $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
12
+
13
+ require 'docdown'
14
+ require 'thor'
15
+
16
+ class DocdownCLI < Thor
17
+
18
+ def initialize(*args)
19
+ super
20
+ @config = options[:config]
21
+ @path = options[:path]
22
+ load("./#{@config}") if @config && File.exist?(@config)
23
+ end
24
+
25
+ default_task :help
26
+
27
+ desc "build", "turns docdown file into docs and a project"
28
+ class_option :path, banner: "path/to/file.md", optional: true, default: 'docdown.md'
29
+ class_option :config, banner: "path/to/docdown_config.rb", default: 'docdown.rb'
30
+ def build
31
+
32
+ raise "#{@path} does not exist" unless File.exist?(@path)
33
+ contents = File.read(@path)
34
+ dir = File.expand_path("../project", @path)
35
+
36
+ FileUtils.remove_entry_secure(dir) if Dir.exist?(dir)
37
+ FileUtils.mkdir_p(dir)
38
+
39
+ Dir.chdir(dir) do
40
+ @output = Docdown::Parser.new(contents).to_md
41
+ end
42
+ File.open("README.md", "w") {|f| f.write @output }
43
+ end
44
+
45
+ end
46
+
47
+ DocdownCLI.start(ARGV)
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'docdown/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "docdown"
8
+ gem.version = Docdown::VERSION
9
+ gem.authors = ["Richard Schneeman"]
10
+ gem.email = ["richard.schneeman+rubygems@gmail.com"]
11
+ gem.description = %q{docdown turns docs to runable code}
12
+ gem.summary = %q{docdown generates runable code from docs}
13
+ gem.homepage = "https://github.com/schneems/docdown"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+
22
+ gem.add_dependency "thor"
23
+ gem.add_dependency "repl_runner"
24
+
25
+ gem.add_development_dependency "rake"
26
+ gem.add_development_dependency "mocha"
27
+ end
28
+
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+
3
+ require 'docdown/version'
4
+
5
+ module Docdown
6
+ extend self
7
+
8
+ def code_command_from_keyword(keyword, *args)
9
+ klass = code_command(keyword.to_sym)
10
+ cc = klass.new(*args)
11
+ cc.keyword = keyword
12
+ cc
13
+ end
14
+
15
+ def code_lookup
16
+ @code_lookup ||= {}
17
+ end
18
+
19
+ def code_command(keyword)
20
+ code_lookup[:"#{keyword}"] || Docdown::CodeCommands::NoSuchCommand
21
+ end
22
+
23
+ def known_commands
24
+ code_lookup.keys
25
+ end
26
+
27
+ def register_code_command(keyword, klass)
28
+ code_lookup[keyword] = klass
29
+ end
30
+
31
+ def configure(&block)
32
+ yield self
33
+ end
34
+ end
35
+
36
+ require 'docdown/parser'
37
+ require 'docdown/code_command'
@@ -0,0 +1,37 @@
1
+ module Docdown
2
+ class CodeCommand
3
+ attr_accessor :hidden, :render_result, :command, :contents, :keyword
4
+
5
+ alias :hidden? :hidden
6
+ alias :render_result? :render_result
7
+
8
+ def initialize(arg)
9
+
10
+ end
11
+
12
+ # returns the markedup command
13
+ # do not over-write unless you call super
14
+ def render
15
+ result = self.call
16
+ return [to_md, result].join("\n") if render_result?
17
+ return "" if hidden?
18
+ to_md
19
+ end
20
+
21
+ def push(contents)
22
+ @contents ||= ""
23
+ @contents << contents
24
+ end
25
+ alias :<< :push
26
+
27
+ # executes command to build project
28
+ def call
29
+ raise "not implemented"
30
+ end
31
+ end
32
+ end
33
+
34
+ require 'docdown/code_commands/bash'
35
+ require 'docdown/code_commands/write'
36
+ require 'docdown/code_commands/repl'
37
+ require 'docdown/code_commands/no_such_command'
@@ -0,0 +1,23 @@
1
+ module Docdown
2
+ module CodeCommands
3
+ class Bash < Docdown::CodeCommand
4
+ def initialize(command)
5
+ @command = command
6
+ @contents = ""
7
+ end
8
+
9
+ def call
10
+ puts "Executing: #{to_md.inspect}"
11
+ `#{@command} #{contents} 2>&1`
12
+ end
13
+
14
+ def to_md
15
+ "$ #{@command} #{contents}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ Docdown.register_code_command(:bash, Docdown::CodeCommands::Bash)
23
+ Docdown.register_code_command(:'$', Docdown::CodeCommands::Bash)
@@ -0,0 +1,6 @@
1
+ module Docdown
2
+ module CodeCommands
3
+ class NoSuchCommand < Docdown::CodeCommand
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,38 @@
1
+ require 'repl_runner'
2
+
3
+ module Docdown
4
+ module CodeCommands
5
+ class Repl < Docdown::CodeCommand
6
+ def initialize(command)
7
+ @command = command
8
+ @contents = ""
9
+ end
10
+
11
+ def keyword=(keyword)
12
+ @keyword = keyword
13
+ puts keyword
14
+ if keyword.to_s == "repl"
15
+ command_array = @command.split(" ")
16
+ puts command_array.inspect
17
+ @keyword = command_array.first
18
+ else
19
+ @command = "#{keyword} #{@command}"
20
+ end
21
+ end
22
+
23
+ def call
24
+ puts @contents.inspect
25
+ zip = ReplRunner.new(:"#{keyword}", @command).zip(contents.strip)
26
+ @result = zip.flatten.join("\n")
27
+ end
28
+
29
+ def to_md
30
+ "$ #{@command}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ Docdown.register_code_command(:repl, Docdown::CodeCommands::Repl)
38
+ Docdown.register_code_command(:irb, Docdown::CodeCommands::Repl)
@@ -0,0 +1,27 @@
1
+ module Docdown
2
+ module CodeCommands
3
+ class Write < Docdown::CodeCommand
4
+ def initialize(filename)
5
+ @filename = filename
6
+ @dir = File.expand_path("../", @filename)
7
+ end
8
+
9
+ # todo diff file if it already exists
10
+ def to_md
11
+ "In file `#{@filename}` add:\n#{contents}"
12
+ end
13
+
14
+ def call
15
+ puts "writing to : #{@filename}"
16
+ FileUtils.mkdir_p(@dir)
17
+ File.open(@filename, "w") do |f|
18
+ f.write(contents)
19
+ end
20
+ contents
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ Docdown.register_code_command(:write, Docdown::CodeCommands::Write)