rundoc 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +70 -39
- data/bin/rundoc +12 -4
- data/lib/rundoc/code_command/file_command/append.rb +14 -11
- data/lib/rundoc/code_command/file_command/remove.rb +6 -5
- data/lib/rundoc/code_command/rundoc_command.rb +1 -1
- data/lib/rundoc/code_command/write.rb +22 -7
- data/lib/rundoc/code_command.rb +6 -2
- data/lib/rundoc/code_section.rb +30 -11
- data/lib/rundoc/parser.rb +1 -1
- data/lib/rundoc/version.rb +2 -2
- data/rundoc.gemspec +3 -3
- data/test/fixtures/rails_4/rundoc.md +151 -188
- data/test/fixtures/rails_5/rundoc.md +443 -0
- data/test/fixtures/rails_5_beta/rundoc.md +445 -0
- data/test/rundoc/code_commands/append_file_test.rb +32 -5
- data/test/rundoc/code_commands/remove_contents_test.rb +2 -3
- data/test/rundoc/code_section_test.rb +92 -0
- data/test/rundoc/parser_test.rb +6 -6
- data/test/rundoc/regex_test.rb +5 -5
- data/test/test_helper.rb +0 -2
- metadata +34 -17
- data/Gemfile.lock +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7935527c5d717e2c4bdc0883a285dd3c7f834f65
|
4
|
+
data.tar.gz: ffc9bf341d82df737a5dc3ba4bb557160ae049b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4839a376fc7911464bfd37ec2a64cc824963a52bef72d1e9e4876c07c8e1f5d6d1d99bab48243ef1c769cb98dabf186624dfe4ecf5a411480a6a748fd0293ab
|
7
|
+
data.tar.gz: 6cd4c38c55413efe85e174b561f39e99bc5788d21e2f63e93cef0c709563609a3864f704cb05c8c04b139d999ef789addeda7105b0b71c8f524890cc4aad2a4d
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
-
|
1
|
+
# RunDOC
|
2
|
+
|
3
|
+
![](https://www.dropbox.com/s/u354td51brynr4h/Screenshot%202017-05-09%2009.36.33.png?dl=1)
|
2
4
|
|
3
5
|
## What
|
4
6
|
|
5
|
-
|
7
|
+
This library allows you to "run" your docs and embed the code as well as results back into the documentation.
|
8
|
+
|
9
|
+
Write in a runDOC compatible markdown format, then run your docs to generate matching projects. Instead of writing a tutorial and then building an example separately, your documentation can build the example app for you. Not only does this keep your doc writing DRY, it also enforces consistency and accuracy. If you make a typo in your docs your project won't build...you'll get early warning and be able to fix it before it has the opportunity to confuse your reader.
|
10
|
+
|
11
|
+
Think of runDOC as your ever-vigilant tech editor and writing partner.
|
6
12
|
|
7
|
-
|
13
|
+
Once docs are run, they output a project and fully valid markdown doc (without any of the special runDOC tags). You could configure your project to be automatically pushed to github or anything else you want afterwards, check out the config section.
|
8
14
|
|
9
|
-
|
15
|
+
Write more technical content, faster and with a better consistency by using runDOC.
|
10
16
|
|
11
17
|
## Why
|
12
18
|
|
@@ -17,13 +23,13 @@ documentation at the same time. I enjoyed the experience but having to do both e
|
|
17
23
|
While I was writing the course I dreamed of a system where the docs and the
|
18
24
|
code could automatically stay in sync. One where if I had a typo in my tutorials, an automatic tech-editor would know and tell me. One where I couldn't accidentally skip over critical sections leaving true novices confused.
|
19
25
|
|
20
|
-
Dream no more, because
|
26
|
+
Dream no more, because runDOC does just that:
|
21
27
|
|
22
28
|
Write docs, build software.
|
23
29
|
|
24
30
|
## Isn't this Overkill?
|
25
31
|
|
26
|
-
No. Many new doc writers skip steps accidentally, or omit lines of code with `...` and assume their readers can follow along. Even if this is true for 80% of your users, 20% of people will become frustrated and may give up as a result. I found by including [check steps](http://schneems.com/post/60359275700/prepare-do-test-make-your-technical-writing-shine) such as running `ls` to ensure directory contents were the difference between good docs and great ones. The only problem: the output of `ls` on a Rails 4.0.0 and 4.0.1 project may be different. So the only way to ensure output is to actually run the command and copy it into your docs. With
|
32
|
+
No. Many new doc writers skip steps accidentally, or omit lines of code with `...` and assume their readers can follow along. Even if this is true for 80% of your users, 20% of people will become frustrated and may give up as a result. I found by including [check steps](http://schneems.com/post/60359275700/prepare-do-test-make-your-technical-writing-shine) such as running `ls` to ensure directory contents were the difference between good docs and great ones. The only problem: the output of `ls` on a Rails 4.0.0 and 4.0.1 project may be different. So the only way to ensure output is to actually run the command and copy it into your docs. With runDOC you don't need to do that. Rundoc runs the command then it can insert the output for you.
|
27
33
|
|
28
34
|
If you don't intend on updating or revising your content, then this project is overkill. On the other hand if you're writing docs without the intent of revising them, you probably shouldn't be writing technical docs.
|
29
35
|
|
@@ -46,7 +52,7 @@ gem 'rundoc`
|
|
46
52
|
Run the `rundoc build` command on any markdown file
|
47
53
|
|
48
54
|
```sh
|
49
|
-
$ rundoc build --path
|
55
|
+
$ rundoc build --path runDOC.md
|
50
56
|
```
|
51
57
|
|
52
58
|
Note: This command will create and manipulate directories in the working directory of your source markdown file. Best practice is to have your source markdown file in it's own empty directory.
|
@@ -56,20 +62,19 @@ This will generate a project folder with your project in it, and a markdown READ
|
|
56
62
|
## Write it:
|
57
63
|
|
58
64
|
Rundoc uses github flavored markdown. This means you write like normal but in your code sections
|
59
|
-
you can add special annotations that when run through
|
65
|
+
you can add special annotations that when run through runDOC can
|
60
66
|
generate a project.
|
61
67
|
|
62
|
-
All
|
68
|
+
All runDOC commands are prefixed with three colons `:::` and are inclosed in a code block a
|
63
69
|
command such as `$` which is an alias for `bash` commands like this:
|
64
70
|
|
65
71
|
```
|
66
|
-
|
72
|
+
:::> $ git init .
|
67
73
|
```
|
68
74
|
|
69
75
|
Nothing before the three colons matters. The space between the colons
|
70
76
|
and the command is optional.
|
71
77
|
|
72
|
-
|
73
78
|
If you don't want the command to output to your markdown document you
|
74
79
|
can add a minus symbol `-` to the end to prevent it from being
|
75
80
|
rendered.
|
@@ -78,13 +83,13 @@ rendered.
|
|
78
83
|
:::- $ git init .
|
79
84
|
```
|
80
85
|
|
81
|
-
Note: If all commands inside of a code block are hidden, the entire codeblock will not be rendered.
|
86
|
+
> Note: If all commands inside of a code block are hidden, the entire codeblock will not be rendered.
|
82
87
|
|
83
88
|
If you want the output of the actual command to be rendered to
|
84
|
-
the screen you can use
|
89
|
+
the screen you can use two arrows so that:
|
85
90
|
|
86
91
|
```
|
87
|
-
|
92
|
+
:::>> $ ls
|
88
93
|
```
|
89
94
|
|
90
95
|
This code block might generate an output something like this to your markdown doc:
|
@@ -95,19 +100,29 @@ This code block might generate an output something like this to your markdown do
|
|
95
100
|
Gemfile.lock Rakefile config db lib public test vendor
|
96
101
|
```
|
97
102
|
|
98
|
-
That's the syntax, let's look at different
|
103
|
+
That's the syntax, let's look at different runDOC commands
|
104
|
+
|
105
|
+
## Rendering Cheat Sheet
|
106
|
+
|
107
|
+
An arrow `>` is shorthand for "render this" and a dash `-` is shorthand for skip this section. The posions two positions are command first and result second. You can skip a trailing `-`.
|
108
|
+
|
109
|
+
|
110
|
+
- `:::>` (yes command, not result)
|
111
|
+
- `:::>>` (yes command, yes result)
|
112
|
+
- `:::-` (not command, not result)
|
113
|
+
- `:::->` (not command, yes result)
|
99
114
|
|
100
115
|
## Shell Commands
|
101
116
|
|
102
117
|
Current Commands:
|
103
118
|
|
104
119
|
- `$`
|
105
|
-
- `fail
|
120
|
+
- `fail.$`
|
106
121
|
|
107
122
|
Anything you pass to `$` will be run in a shell. Any items below the command will be passed into the stdin of the bash command so:
|
108
123
|
|
109
124
|
```
|
110
|
-
|
125
|
+
:::>> $ tail -n 2
|
111
126
|
foo
|
112
127
|
bar
|
113
128
|
baz
|
@@ -122,12 +137,12 @@ Would output:
|
|
122
137
|
bahz
|
123
138
|
```
|
124
139
|
|
125
|
-
This could be useful if you are running an interactive command such as `play new` which requires user input. For more fine grained input you'll need to use a custom repl object (will be covered later).
|
140
|
+
This STDIN feature could be useful if you are running an interactive command such as `play new` which requires user input. For more fine grained input you'll need to use a custom repl object (will be covered later).
|
126
141
|
|
127
142
|
If a shell command returns a non-zero exit status an error will be raised, if you expect a command to fail you can run it with `fail.$` keyword
|
128
143
|
|
129
144
|
```
|
130
|
-
|
145
|
+
:::>> fail.$ cat /dev/null/foo
|
131
146
|
```
|
132
147
|
|
133
148
|
Even though this command returns a non zero exit status, the contents of the command will be written since we're stating that we don't care if the command fails. This would be the output:
|
@@ -142,14 +157,14 @@ Some commands may be custom, for example when running `cd` you likely want to ch
|
|
142
157
|
|
143
158
|
|
144
159
|
```
|
145
|
-
|
146
|
-
|
160
|
+
:::>> $ cd myapp/config
|
161
|
+
:::>> $ cat database.yml
|
147
162
|
```
|
148
163
|
|
149
|
-
However this command would fall on
|
164
|
+
However this command would fall on its face:
|
150
165
|
|
151
166
|
```
|
152
|
-
|
167
|
+
:::>> $ cd myapp/config && cat database.yml
|
153
168
|
```
|
154
169
|
|
155
170
|
These custom commands are kept to a minimum, and for the most part behave as you would expect them to. Write your docs as you normally would and check the output frequently.
|
@@ -164,10 +179,10 @@ Current Commands:
|
|
164
179
|
- `file.append`
|
165
180
|
- `file.remove`
|
166
181
|
|
167
|
-
Use the `
|
182
|
+
Use the `file.write` keyword followed by a filename, on the next line(s) put the contents of the file
|
168
183
|
|
169
184
|
```
|
170
|
-
|
185
|
+
:::> file.write config/routes.rb
|
171
186
|
|
172
187
|
Example::Application.routes.draw do
|
173
188
|
root :to => "pages#index"
|
@@ -181,7 +196,7 @@ Use the `filewrite` keyword followed by a filename, on the next line(s) put the
|
|
181
196
|
If you wanted to change `users` to `products` you could write to the same file again.
|
182
197
|
|
183
198
|
```
|
184
|
-
|
199
|
+
:::> file.write config/routes.rb
|
185
200
|
Example::Application.routes.draw do
|
186
201
|
root :to => "pages#index"
|
187
202
|
|
@@ -196,7 +211,7 @@ To fully delete files use bash `$` command such as `::: $ rm foo.rb`.
|
|
196
211
|
To add contents to a file you can use `file.append`
|
197
212
|
|
198
213
|
```
|
199
|
-
|
214
|
+
:::>> file.append myapp/Gemfile
|
200
215
|
gem 'pg'
|
201
216
|
gem 'sextant', group: :development
|
202
217
|
gem 'wicked'
|
@@ -206,7 +221,7 @@ To add contents to a file you can use `file.append`
|
|
206
221
|
The contents of the file (in this example a file named `Gemfile`) will remain unchanged, but the contents of the `file.append` block will now appear in the bottom of the file. If you want to append the contents to a specific part of the file instead of the end of the file you can specify line number by putting a hash (`#`) then a number following it.
|
207
222
|
|
208
223
|
```
|
209
|
-
|
224
|
+
:::>> file.append myapp/Gemfile#22
|
210
225
|
gem 'rails_12factor'
|
211
226
|
```
|
212
227
|
This will add the `gem 'rails_12factor'` on line 22 of the file `myapp/Gemfile`. If line 22 has existing contents, they will be bumped down to line 23.
|
@@ -214,7 +229,7 @@ This will add the `gem 'rails_12factor'` on line 22 of the file `myapp/Gemfile`.
|
|
214
229
|
Some times you may want to remove a small amount of text from an existing file. You can do this using `file.remove`, you pass in the contents you want removed:
|
215
230
|
|
216
231
|
```
|
217
|
-
|
232
|
+
:::>> file.remove myapp/Gemfile
|
218
233
|
gem 'sqlite3'
|
219
234
|
```
|
220
235
|
|
@@ -222,20 +237,19 @@ When this is run, the file `Gemfile` will be modified to not include `gem 'sqlit
|
|
222
237
|
|
223
238
|
Note: `file.remove` currently requires a very explicit match so things like double versus single quotes, whitespace, and letter case all matter. Current best practice is to only use it for single line removals.
|
224
239
|
|
225
|
-
|
226
240
|
## Pipe
|
227
241
|
|
228
242
|
Commands:
|
229
243
|
- `|`
|
230
244
|
- `pipe` (aliased `|`)
|
231
245
|
|
232
|
-
Sometimes you need to need to pass data from one command to another. To do this there is a provided pipe command
|
246
|
+
Sometimes you need to need to pass data from one command to another. To do this there is a provided pipe command `|`.
|
233
247
|
|
234
248
|
Let's say you want to output the first 23 lines of a file but you don't want to confuse your users with an additional pipe command in your shell line you could write something like this:
|
235
249
|
|
236
250
|
```sh
|
237
|
-
|
238
|
-
|
251
|
+
:::> $ cat config/database.yml
|
252
|
+
:::>> | $ head -n 23
|
239
253
|
```
|
240
254
|
|
241
255
|
Anything after the pipe `|` will generate a new command with the output of the previous command passed to it. The pipe command will only ouput its result, so the user will not know it was even executed.
|
@@ -245,7 +259,7 @@ This command is currently hacked together, and needs a refactor. Use it, but if
|
|
245
259
|
|
246
260
|
## Configure
|
247
261
|
|
248
|
-
You can configure your docs in your docs use the `
|
262
|
+
You can configure your docs in your docs use the `runDOC` command
|
249
263
|
|
250
264
|
```
|
251
265
|
:::- rundoc
|
@@ -272,7 +286,7 @@ This will eval any code you put under that line (in Ruby). If you want to run so
|
|
272
286
|
|
273
287
|
**Project Root**
|
274
288
|
|
275
|
-
By default your app builds in a `tmp` directory. If any failures occur the results will remain in `tmp`. On a successful build the contents are copied over to `project`. If you are generating a new rails project in your code `$ rails new myapp`. Then the finished directory would be in `project/myapp`. If you don't like the `./project` prefix you could tell
|
289
|
+
By default your app builds in a `tmp` directory. If any failures occur the results will remain in `tmp`. On a successful build the contents are copied over to `project`. If you are generating a new rails project in your code `$ rails new myapp`. Then the finished directory would be in `project/myapp`. If you don't like the `./project` prefix you could tell runDOC to output contents in `./myapp` instead.
|
276
290
|
|
277
291
|
```
|
278
292
|
:::- rundoc
|
@@ -300,10 +314,27 @@ This command `filter_sensitive` can be called multiple times with different valu
|
|
300
314
|
|
301
315
|
This is a section for brainstorming. If it's here it's not guaranteed to get worked on, but it will be considered.
|
302
316
|
|
303
|
-
-
|
304
|
-
-
|
305
|
-
|
317
|
+
- Seperate parsing from running. This will help for easier linting of syntax etc.
|
318
|
+
- Cache SHAs and output of each code block. If one sha changes, re-generate all code blocks, otherwise allow a re-render without code execution. Configure a check sum for busting the cache for instance a new version of Rails is released.
|
319
|
+
|
320
|
+
|
306
321
|
- A way to run background processes indefinitely such as `rails server`
|
322
|
+
- Maybe a way to truncate them after only a period of time such as grab a few lines of `heroku local`.
|
323
|
+
|
324
|
+
|
325
|
+
```
|
326
|
+
:::> background.start(command: "rails server")
|
327
|
+
```
|
328
|
+
|
329
|
+
```
|
330
|
+
:::>> background.read("rails server")
|
331
|
+
:::> | $ head -n 23
|
332
|
+
:::> background.clear
|
333
|
+
```
|
334
|
+
|
335
|
+
|
336
|
+
- Breakpoints?
|
337
|
+
- Better line matching for backtrace
|
338
|
+
- `-=` command (runs command, only shows output, does not show command) ?
|
307
339
|
- An easy test syntax?
|
308
340
|
- Screenshot tool(s) ?!?!?!?!?!?! :)
|
309
|
-
|
data/bin/rundoc
CHANGED
@@ -28,19 +28,27 @@ class RundocCLI < Thor
|
|
28
28
|
desc "build", "turns rundoc file into docs and a project"
|
29
29
|
class_option :path, banner: "path/to/file.md", optional: true, default: 'rundoc.md'
|
30
30
|
def build
|
31
|
-
raise "#{@path} does not exist"
|
31
|
+
raise "#{@path} does not exist" unless File.exist?(@path)
|
32
|
+
raise "Expecting #{@path} to be a rundoc markdown file" unless File.file?(@path)
|
32
33
|
source_contents = File.read(@path)
|
33
34
|
tmp_dir = @working_dir.join("tmp")
|
34
35
|
|
35
36
|
FileUtils.remove_entry_secure(tmp_dir) if tmp_dir.exist?
|
36
37
|
tmp_dir.mkdir
|
38
|
+
banner = <<~HEREDOC
|
39
|
+
<!-- STOP
|
40
|
+
This file was generated by a rundoc script, do not modify it.
|
41
|
+
|
42
|
+
Instead modify the rundoc script and re-run it.
|
43
|
+
|
44
|
+
Command: #{ $0 } #{$*.join(' ')}
|
45
|
+
STOP -->
|
46
|
+
HEREDOC
|
37
47
|
|
38
48
|
puts "== Running your docs"
|
39
49
|
Dir.chdir(tmp_dir) do
|
40
50
|
@output = Rundoc::Parser.new(source_contents, Rundoc.parser_options).to_md
|
41
51
|
Rundoc.sanitize(@output)
|
42
|
-
banner = "<!-- STOP\nThis file was generated by a rundoc script, don't modify it. \n"
|
43
|
-
banner << "Instead modify the rundoc script and re-run it.\nSTOP -->"
|
44
52
|
@output = "#{banner}\n#{@output}"
|
45
53
|
end
|
46
54
|
|
@@ -65,8 +73,8 @@ class RundocCLI < Thor
|
|
65
73
|
|
66
74
|
FileUtils.remove_entry_secure(tmp_dir) if tmp_dir.exist?
|
67
75
|
|
68
|
-
puts "== Done, writing original source to #{project_dir}/source.md"
|
69
76
|
source_path = project_dir.join("README.md")
|
77
|
+
puts "== Done, writing original source to #{source_path}"
|
70
78
|
File.open(source_path, "w") { |f| f.write @output }
|
71
79
|
|
72
80
|
puts "== Copying source"
|
@@ -1,18 +1,23 @@
|
|
1
1
|
class Rundoc::CodeCommand::FileCommand
|
2
2
|
class Append < Rundoc::CodeCommand
|
3
|
+
include FileUtil
|
3
4
|
|
4
5
|
def initialize(filename)
|
5
6
|
@filename, line = filename.split('#')
|
6
|
-
|
7
|
+
if line
|
8
|
+
@line_number = Integer(line)
|
9
|
+
else
|
10
|
+
@line_number = nil
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
def to_md(env)
|
10
15
|
raise "must call write in its own code section" unless env[:commands].empty?
|
11
16
|
before = env[:before]
|
12
17
|
if @line_number
|
13
|
-
env[:before] = "In file `#{
|
18
|
+
env[:before] = "In file `#{filename}`, on line #{@line_number} add:\n\n#{before}"
|
14
19
|
else
|
15
|
-
env[:before] = "At the end of `#{
|
20
|
+
env[:before] = "At the end of `#{filename}` add:\n\n#{before}"
|
16
21
|
end
|
17
22
|
nil
|
18
23
|
end
|
@@ -36,7 +41,7 @@ class Rundoc::CodeCommand::FileCommand
|
|
36
41
|
|
37
42
|
def insert_contents_into_at_line(doc)
|
38
43
|
lines = doc.lines
|
39
|
-
raise "Expected #{
|
44
|
+
raise "Expected #{filename} to have at least #{@line_number} but only has #{lines.count}" if lines.count < @line_number
|
40
45
|
result = []
|
41
46
|
lines.each_with_index do |line, index|
|
42
47
|
line_number = index.next
|
@@ -50,19 +55,17 @@ class Rundoc::CodeCommand::FileCommand
|
|
50
55
|
end
|
51
56
|
|
52
57
|
def call(env = {})
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
doc = File.read(@filename)
|
58
|
+
mkdir_p
|
59
|
+
doc = File.read(filename)
|
57
60
|
if @line_number
|
58
|
-
puts "Writing to: '#{
|
61
|
+
puts "Writing to: '#{filename}' line #{@line_number} with: #{contents.inspect}"
|
59
62
|
doc = insert_contents_into_at_line(doc)
|
60
63
|
else
|
61
|
-
puts "Appending to file: '#{
|
64
|
+
puts "Appending to file: '#{filename}' with: #{contents.inspect}"
|
62
65
|
doc = concat_with_newline(doc, contents)
|
63
66
|
end
|
64
67
|
|
65
|
-
File.open(
|
68
|
+
File.open(filename, "w") do |f|
|
66
69
|
f.write(doc)
|
67
70
|
end
|
68
71
|
contents
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Rundoc::CodeCommand::FileCommand
|
2
2
|
class Remove < Rundoc::CodeCommand
|
3
|
+
include FileUtil
|
3
4
|
|
4
5
|
def initialize(filename)
|
5
6
|
@filename = filename
|
@@ -8,19 +9,19 @@ class Rundoc::CodeCommand::FileCommand
|
|
8
9
|
def to_md(env)
|
9
10
|
raise "must call write in its own code section" unless env[:commands].empty?
|
10
11
|
before = env[:before]
|
11
|
-
env[:before] = "In file `#{
|
12
|
+
env[:before] = "In file `#{filename}` remove:\n\n#{before}"
|
12
13
|
nil
|
13
14
|
end
|
14
15
|
|
15
16
|
def call(env = {})
|
16
|
-
puts "Deleting '#{contents.strip}' from #{
|
17
|
-
raise "#{
|
17
|
+
puts "Deleting '#{contents.strip}' from #{filename}"
|
18
|
+
raise "#{filename} does not exist" unless File.exist?(filename)
|
18
19
|
|
19
20
|
regex = /^\s*#{Regexp.quote(contents)}/
|
20
|
-
doc = File.read(
|
21
|
+
doc = File.read(filename)
|
21
22
|
doc.sub!(regex, '')
|
22
23
|
|
23
|
-
File.open(
|
24
|
+
File.open(filename, "w") do |f|
|
24
25
|
f.write(doc)
|
25
26
|
end
|
26
27
|
contents
|
@@ -1,6 +1,23 @@
|
|
1
1
|
module Rundoc
|
2
2
|
class CodeCommand
|
3
|
+
module FileUtil
|
4
|
+
def filename
|
5
|
+
files = Dir.glob(@filename)
|
6
|
+
if files.length > 1
|
7
|
+
raise "Filename glob #{@filename.inspect} matched more than one file. Be more specific to only match one file. Matches:\n" + files.join(" \n")
|
8
|
+
end
|
9
|
+
files.first || @filename
|
10
|
+
end
|
11
|
+
|
12
|
+
def mkdir_p
|
13
|
+
dir = File.expand_path("../", filename)
|
14
|
+
FileUtils.mkdir_p(dir)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
3
18
|
class Write < Rundoc::CodeCommand
|
19
|
+
include FileUtil
|
20
|
+
|
4
21
|
def initialize(filename)
|
5
22
|
@filename = filename
|
6
23
|
end
|
@@ -8,16 +25,14 @@ module Rundoc
|
|
8
25
|
def to_md(env)
|
9
26
|
raise "must call write in its own code section" unless env[:commands].empty?
|
10
27
|
before = env[:before]
|
11
|
-
env[:before] = "In file `#{
|
28
|
+
env[:before] = "In file `#{filename}` write:\n\n#{before}"
|
12
29
|
nil
|
13
30
|
end
|
14
31
|
|
15
32
|
def call(env = {})
|
16
|
-
puts "Writing to: '#{
|
17
|
-
|
18
|
-
|
19
|
-
FileUtils.mkdir_p(dir)
|
20
|
-
File.open(@filename, "w") do |f|
|
33
|
+
puts "Writing to: '#{filename}'"
|
34
|
+
mkdir_p
|
35
|
+
File.open(filename, "w") do |f|
|
21
36
|
f.write(contents)
|
22
37
|
end
|
23
38
|
contents
|
@@ -31,4 +46,4 @@ Rundoc.register_code_command(:write, Rundoc::CodeCommand::Write)
|
|
31
46
|
Rundoc.register_code_command(:'file.write', Rundoc::CodeCommand::Write)
|
32
47
|
|
33
48
|
require 'rundoc/code_command/file_command/append'
|
34
|
-
require 'rundoc/code_command/file_command/remove'
|
49
|
+
require 'rundoc/code_command/file_command/remove'
|
data/lib/rundoc/code_command.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
module Rundoc
|
2
2
|
class CodeCommand
|
3
|
-
attr_accessor :
|
4
|
-
alias :hidden? :hidden
|
3
|
+
attr_accessor :render_result, :render_command, :command, :contents, :keyword
|
5
4
|
alias :render_result? :render_result
|
5
|
+
alias :render_command? :render_command
|
6
6
|
|
7
7
|
def initialize(arg)
|
8
8
|
end
|
9
9
|
|
10
|
+
def hidden?
|
11
|
+
!render_command? && !render_result?
|
12
|
+
end
|
13
|
+
|
10
14
|
def not_hidden?
|
11
15
|
!hidden?
|
12
16
|
end
|
data/lib/rundoc/code_section.rb
CHANGED
@@ -40,7 +40,7 @@ module Rundoc
|
|
40
40
|
|
41
41
|
def render
|
42
42
|
result = []
|
43
|
-
env
|
43
|
+
env = {}
|
44
44
|
env[:commands] = []
|
45
45
|
env[:before] = "#{fence}#{lang}"
|
46
46
|
env[:after] = "#{fence}"
|
@@ -57,11 +57,12 @@ module Rundoc
|
|
57
57
|
|
58
58
|
env[:commands] << { object: code_command, output: code_output, command: code_line}
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
tmp_result = []
|
61
|
+
tmp_result << code_line if code_command.render_command?
|
62
|
+
tmp_result << code_output if code_command.render_result?
|
63
|
+
|
64
|
+
result << tmp_result unless code_command.hidden?
|
65
|
+
result
|
65
66
|
end
|
66
67
|
|
67
68
|
return "" if hidden?
|
@@ -112,16 +113,34 @@ module Rundoc
|
|
112
113
|
command = match[:command]
|
113
114
|
tag = match[:tag]
|
114
115
|
statement = match[:statement]
|
115
|
-
|
116
116
|
code_command = Rundoc.code_command_from_keyword(command, statement)
|
117
117
|
|
118
118
|
case tag
|
119
|
-
when
|
120
|
-
code_command.
|
119
|
+
when /\A>>/ # show command, show result
|
120
|
+
code_command.render_command = true
|
121
|
+
code_command.render_result = true
|
122
|
+
when /(\A>\-)|(\A>[^\-]?)/ # show command, not result
|
123
|
+
code_command.render_command = true
|
124
|
+
code_command.render_result = false
|
125
|
+
when /\A\->/ # hide command, show result
|
126
|
+
code_command.render_command = false
|
127
|
+
code_command.render_result = true
|
128
|
+
when /(\A\-)|(\A\-\-)/ # hide command, hide result
|
129
|
+
code_command.render_command = false
|
130
|
+
code_command.render_result = false
|
131
|
+
# ========= DEPRECATED ==========
|
121
132
|
when /\=/
|
122
|
-
|
133
|
+
puts "Deprecated: `:::=` is deprecated use `:::>>` instead"
|
134
|
+
puts " :::>> #{command} #{statement}"
|
135
|
+
code_command.render_command = true
|
136
|
+
code_command.render_result = true
|
123
137
|
when /\s/
|
124
|
-
|
138
|
+
puts "Deprecated: `:::` is deprecated use `:::>` instead"
|
139
|
+
puts " :::> #{command} #{statement}"
|
140
|
+
code_command.render_command = true
|
141
|
+
code_command.render_result = false
|
142
|
+
else
|
143
|
+
raise "Tag is invalid #{tag.inspect}"
|
125
144
|
end
|
126
145
|
|
127
146
|
@stack << "\n" if commands.last.is_a?(Rundoc::CodeCommand)
|
data/lib/rundoc/parser.rb
CHANGED
@@ -5,7 +5,7 @@ module Rundoc
|
|
5
5
|
GITHUB_BLOCK = '^(?<fence>(?<fence_char>~|`){3,})\s*?(?<lang>\w+)?\s*?\n(?<contents>.*?)^\g<fence>\g<fence_char>*\s*?\n'
|
6
6
|
CODEBLOCK_REGEX = /(#{GITHUB_BLOCK})/m
|
7
7
|
COMMAND_REGEX = ->(keyword) {
|
8
|
-
/^#{keyword}(?<tag>(\s
|
8
|
+
/^#{keyword}(?<tag>(\s|=|-|>)?(=|-|>)?)\s*(?<command>(\S)+)\s+(?<statement>.*)$/
|
9
9
|
}
|
10
10
|
|
11
11
|
attr_reader :contents, :keyword, :stack
|
data/lib/rundoc/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Rundoc
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
2
|
+
VERSION = "0.0.2"
|
3
|
+
end
|
data/rundoc.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Rundoc::VERSION
|
9
9
|
gem.authors = ["Richard Schneeman"]
|
10
10
|
gem.email = ["richard.schneeman+rubygems@gmail.com"]
|
11
|
-
gem.description = %q{
|
12
|
-
gem.summary = %q{
|
11
|
+
gem.description = %q{runDOC turns docs to runable code}
|
12
|
+
gem.summary = %q{runDOC generates runable code from docs}
|
13
13
|
gem.homepage = "https://github.com/schneems/rundoc"
|
14
14
|
gem.license = "MIT"
|
15
15
|
|
@@ -18,11 +18,11 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
21
|
gem.add_dependency "thor"
|
23
22
|
gem.add_dependency "repl_runner"
|
24
23
|
|
25
24
|
gem.add_development_dependency "rake"
|
26
25
|
gem.add_development_dependency "mocha"
|
26
|
+
gem.add_development_dependency "test-unit"
|
27
27
|
end
|
28
28
|
|