germinate 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/History.txt +26 -0
- data/README.rdoc +152 -0
- data/Rakefile +43 -0
- data/TODO +140 -0
- data/bin/germ +260 -0
- data/cucumber.yml +2 -0
- data/examples/basic.rb +123 -0
- data/examples/short.rb +19 -0
- data/features/author-formats-article.feature +111 -0
- data/features/author-lists-info.pending_feature +48 -0
- data/features/author-publishes-article-source.feature +5 -0
- data/features/author-publishes-article.feature +57 -0
- data/features/author-republishes-article.feature +5 -0
- data/features/author-selects-hunks.feature +26 -0
- data/features/author-sets-variables.feature +88 -0
- data/features/author-updates-article-source.feature +5 -0
- data/features/author-views-stuff.pending_feature +52 -0
- data/features/bin/quoter +6 -0
- data/features/bin/sorter +4 -0
- data/features/example_articles/bracketing.rb +27 -0
- data/features/example_articles/escaping.txt +13 -0
- data/features/example_articles/excerpt_output.rb +16 -0
- data/features/example_articles/hello.rb +9 -0
- data/features/example_articles/pipelines.txt +25 -0
- data/features/example_articles/regexen.rb +24 -0
- data/features/example_articles/sample_offsets.rb +18 -0
- data/features/example_articles/specials.rb +19 -0
- data/features/example_articles/stderr.rb +10 -0
- data/features/example_articles/wrapping.rb +8 -0
- data/features/example_output/bracketing.out +23 -0
- data/features/example_output/code_samples.txt +186 -0
- data/features/example_output/escaping.out +5 -0
- data/features/example_output/excerpt_output.out +6 -0
- data/features/example_output/hello.txt +1 -0
- data/features/example_output/pipelines.out +28 -0
- data/features/example_output/regexen.txt +22 -0
- data/features/example_output/sample_offsets.txt +15 -0
- data/features/example_output/specials.txt +40 -0
- data/features/example_output/stderr.out +3 -0
- data/features/example_output/wrapping.txt +3 -0
- data/features/step_definitions/germinate.rb +42 -0
- data/features/support/env.rb +20 -0
- data/germinate.gemspec +55 -0
- data/lib/germinate.rb +54 -0
- data/lib/germinate/application.rb +113 -0
- data/lib/germinate/article_editor.rb +20 -0
- data/lib/germinate/formatter.rb +119 -0
- data/lib/germinate/hunk.rb +183 -0
- data/lib/germinate/implicit_insertion.rb +9 -0
- data/lib/germinate/insertion.rb +29 -0
- data/lib/germinate/librarian.rb +293 -0
- data/lib/germinate/origin.rb +5 -0
- data/lib/germinate/pipeline.rb +13 -0
- data/lib/germinate/publisher.rb +57 -0
- data/lib/germinate/reader.rb +266 -0
- data/lib/germinate/selector.rb +136 -0
- data/lib/germinate/shared_style_attributes.rb +54 -0
- data/lib/germinate/shell_process.rb +94 -0
- data/lib/germinate/shell_publisher.rb +19 -0
- data/lib/germinate/simple_publisher.rb +7 -0
- data/lib/germinate/source_file.rb +41 -0
- data/lib/germinate/text_transforms.rb +119 -0
- data/lib/germinate/transform_process.rb +25 -0
- data/lib/germinate/variable.rb +23 -0
- data/sample.rb +14 -0
- data/spec/germinate/application_spec.rb +31 -0
- data/spec/germinate/article_editor_spec.rb +97 -0
- data/spec/germinate/code_hunk_spec.rb +73 -0
- data/spec/germinate/file_hunk_spec.rb +28 -0
- data/spec/germinate/formatter_spec.rb +160 -0
- data/spec/germinate/hunk_spec.rb +84 -0
- data/spec/germinate/implicit_insertion_spec.rb +33 -0
- data/spec/germinate/insertion_spec.rb +19 -0
- data/spec/germinate/librarian_spec.rb +555 -0
- data/spec/germinate/pipeline_spec.rb +34 -0
- data/spec/germinate/process_spec.rb +105 -0
- data/spec/germinate/publisher_spec.rb +130 -0
- data/spec/germinate/reader_spec.rb +385 -0
- data/spec/germinate/selector_spec.rb +121 -0
- data/spec/germinate/shell_publisher_spec.rb +61 -0
- data/spec/germinate/source_file_spec.rb +99 -0
- data/spec/germinate/text_hunk_spec.rb +98 -0
- data/spec/germinate/text_transforms_spec.rb +242 -0
- data/spec/germinate/transform_process_spec.rb +50 -0
- data/spec/germinate/variable_spec.rb +14 -0
- data/spec/germinate_spec.rb +8 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/cucumber.rake +5 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test_germinate.rb +0 -0
- metadata +228 -0
data/.gitignore
ADDED
data/History.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
== 1.2.0 / 2009-07-21
|
2
|
+
|
3
|
+
* 4 major enhancements
|
4
|
+
* Added "publish" command and pluggable publishers
|
5
|
+
* Added builtin publisher "shell" for publishing via shell command
|
6
|
+
* Added variables, settable with the :SET: directive
|
7
|
+
* Added the ability for commands to write changes back to the source file
|
8
|
+
(with backups)
|
9
|
+
* 2 minor enhancements
|
10
|
+
* Refactored standard text transforms to be just another process
|
11
|
+
* Made the list/show/select command arguments easier to use
|
12
|
+
|
13
|
+
== 1.1.0 / 2009-07-12
|
14
|
+
|
15
|
+
* 1 major enhancement
|
16
|
+
* Added post-pipeline excerpting, e.g. $SOURCE|ruby:/def foo/../end/
|
17
|
+
Post-pipeline excerpting executes the process against the entire sample and
|
18
|
+
then excerpts the output.
|
19
|
+
* 1 minor enhancement
|
20
|
+
* Processes applied to $SOURCE will be given the actual source path instead of
|
21
|
+
a temp file
|
22
|
+
|
23
|
+
== 1.0.0 / 2009-07-06
|
24
|
+
|
25
|
+
* 1 major enhancement
|
26
|
+
* Birthday!
|
data/README.rdoc
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
= germinate
|
2
|
+
|
3
|
+
by Avdi Grimm
|
4
|
+
|
5
|
+
http://github.com/devver/germinate/
|
6
|
+
|
7
|
+
== SYNOPSIS
|
8
|
+
|
9
|
+
germ generate > my_article.rb
|
10
|
+
germ format my_article.rb > my_article.txt
|
11
|
+
|
12
|
+
== DESCRIPTION
|
13
|
+
|
14
|
+
Germinate is a tool for writing about code. With Germinate, the source code IS
|
15
|
+
the article.
|
16
|
+
|
17
|
+
For example, given the following source code:
|
18
|
+
|
19
|
+
# #!/usr/bin/env ruby
|
20
|
+
# :BRACKET_CODE: <pre>, </pre>
|
21
|
+
# :PROCESS: ruby, "ruby %f"
|
22
|
+
|
23
|
+
# :SAMPLE: hello
|
24
|
+
def hello(who)
|
25
|
+
puts "Hello, #{who}"
|
26
|
+
end
|
27
|
+
|
28
|
+
hello("World")
|
29
|
+
|
30
|
+
# :TEXT:
|
31
|
+
# Check out my amazing program! Here's the hello method:
|
32
|
+
# :INSERT: @hello:/def/../end/
|
33
|
+
|
34
|
+
# And here's the output:
|
35
|
+
# :INSERT: @hello|ruby
|
36
|
+
|
37
|
+
When we run the <tt>germ format</tt> command the following output is generated:
|
38
|
+
|
39
|
+
Check out my amazing program! Here's the hello method:
|
40
|
+
<pre>
|
41
|
+
def hello(who)
|
42
|
+
puts "Hello, #{who}"
|
43
|
+
end
|
44
|
+
</pre>
|
45
|
+
And here's the output:
|
46
|
+
<pre>
|
47
|
+
Hello, World
|
48
|
+
</pre>
|
49
|
+
|
50
|
+
To get a better idea of how this works, please take a look at
|
51
|
+
link:examples/basic.rb, or run:
|
52
|
+
|
53
|
+
germ generate > basic.rb
|
54
|
+
|
55
|
+
To generate an example article to play with.
|
56
|
+
|
57
|
+
Germinate is particularly useful for writing articles, such as blog posts, which
|
58
|
+
contain code excerpts. Instead of forcing you to keep a source code file and an
|
59
|
+
article document in sync throughout the editing process, the Germinate motto is
|
60
|
+
"The source code IS the article". Specially marked comment sections in your
|
61
|
+
code file become the article text. Wherever you need to reference the source
|
62
|
+
code in the article, use insertion directives to tell Germinate what parts of
|
63
|
+
the code to excerpt. An advanced selector syntax enables you to be very
|
64
|
+
specific about which lines of code you want to insert.
|
65
|
+
|
66
|
+
If you also want to show the output of your code, Germinate has you covered.
|
67
|
+
Special "process" directives enable you to define arbitrary commands which can
|
68
|
+
be run on your code. The output of the command then becomes the excerpt text.
|
69
|
+
You can define an arbitrary number of processes and have different excerpts
|
70
|
+
showing the same code as processed by different commands. You can even string
|
71
|
+
processes together into pipelines.
|
72
|
+
|
73
|
+
Development of Germinate is graciously sponsored by Devver, purveyor of fine
|
74
|
+
cloud-based services to busy Ruby developers. If you like this tool please
|
75
|
+
check them out at http://devver.net.
|
76
|
+
|
77
|
+
== WHAT GERMINATE IS NOT
|
78
|
+
|
79
|
+
Germinate is not a markup language like HTML, Textile, or Markdown. It is
|
80
|
+
completely markup-agnostic, although it can be configured to automatically
|
81
|
+
pre-process your articles with markup tools before publishing. Germinate
|
82
|
+
concerns itslf strictly with bringing together your words and your code, and
|
83
|
+
with automating the process of publishing the finished product.
|
84
|
+
|
85
|
+
Germinate is not a code documentation tool. While it facilitates the process of
|
86
|
+
writing *about* code, it has no understanding of the code itself. Germinate is
|
87
|
+
orthogonal to tools such as RDoc or Doxygen.
|
88
|
+
|
89
|
+
Germinate is not a blogging engine. It is designed to integrate with your
|
90
|
+
favorite blogging engine through publisher plugins.
|
91
|
+
|
92
|
+
Germinate is none of these things, but it is designed to complement all of
|
93
|
+
them.
|
94
|
+
|
95
|
+
== FEATURES
|
96
|
+
|
97
|
+
* Language and markup agnostic
|
98
|
+
* Advanced selector syntax for excerpting code
|
99
|
+
* Define arbitrary command pipelines to preprocess excerpts
|
100
|
+
* Article text is reformatted to be more compatible with popular blogging
|
101
|
+
engines, e.g. WordPress.
|
102
|
+
* Extensable with plugins for publishing to Gist, WordPress, etc.
|
103
|
+
* Introspection commands make it easy to experiment
|
104
|
+
|
105
|
+
== KNOWN ISSUES
|
106
|
+
|
107
|
+
* Directive syntax conflicts with RDoc. Doh!
|
108
|
+
* Focus is currently on features. Documentation is lacking. Have a look at the
|
109
|
+
features/ directory to get a better idea of various Germinate features.
|
110
|
+
|
111
|
+
== FUTURE
|
112
|
+
|
113
|
+
* Integration with blogging platforms, e.g. WordPress
|
114
|
+
|
115
|
+
== REQUIREMENTS
|
116
|
+
|
117
|
+
* Ruby 1.8
|
118
|
+
* main
|
119
|
+
* fattr
|
120
|
+
* ick
|
121
|
+
* orderedhash
|
122
|
+
* arrayfields
|
123
|
+
* alter-ego
|
124
|
+
|
125
|
+
== INSTALL:
|
126
|
+
|
127
|
+
gem install --source http://gems.rubyforge.org devver-germinate
|
128
|
+
|
129
|
+
== LICENSE:
|
130
|
+
|
131
|
+
(The MIT License)
|
132
|
+
|
133
|
+
Copyright (c) 2009
|
134
|
+
|
135
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
136
|
+
a copy of this software and associated documentation files (the
|
137
|
+
'Software'), to deal in the Software without restriction, including
|
138
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
139
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
140
|
+
permit persons to whom the Software is furnished to do so, subject to
|
141
|
+
the following conditions:
|
142
|
+
|
143
|
+
The above copyright notice and this permission notice shall be
|
144
|
+
included in all copies or substantial portions of the Software.
|
145
|
+
|
146
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
147
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
148
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
149
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
150
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
151
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
152
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bones'
|
7
|
+
Bones.setup
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
load 'tasks/setup.rb'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ensure_in_path 'lib'
|
17
|
+
require 'germinate'
|
18
|
+
|
19
|
+
task :default => 'spec:run'
|
20
|
+
|
21
|
+
PROJ.name = 'germinate'
|
22
|
+
PROJ.authors = 'Avdi Grimm'
|
23
|
+
PROJ.email = 'avdi@avdi.org'
|
24
|
+
PROJ.url = 'http://github.com/devver/germinate/'
|
25
|
+
PROJ.version = Germinate::VERSION
|
26
|
+
PROJ.rubyforge.name = 'germinate'
|
27
|
+
|
28
|
+
PROJ.spec.opts << '--color'
|
29
|
+
|
30
|
+
PROJ.ruby_opts = []
|
31
|
+
|
32
|
+
PROJ.readme_file = "README.rdoc"
|
33
|
+
PROJ.rdoc.main = "README.rdoc"
|
34
|
+
PROJ.rdoc.exclude << "features"
|
35
|
+
|
36
|
+
depend_on "ick", "~> 0.3.0"
|
37
|
+
depend_on "fattr", "~> 1.0.3"
|
38
|
+
depend_on "arrayfields", "~> 4.7.3"
|
39
|
+
depend_on "orderedhash", "~> 0.0.6"
|
40
|
+
depend_on "alter-ego", "~> 1.0.0"
|
41
|
+
depend_on "main", "~> 2.8.3"
|
42
|
+
|
43
|
+
# EOF
|
data/TODO
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# -*- mode: org -*-
|
2
|
+
#+SEQ_TODO: TODO | DONE INVALID
|
3
|
+
|
4
|
+
* INVALID Fix bug in `germ select` :bug:
|
5
|
+
CLOSED: [2009-07-12 Sun 18:25]
|
6
|
+
: germ select -s "$SOURCE|ruby" ruby_subprocesses_part_2.rb
|
7
|
+
: F, [2009-07-12T17:41:17.331337 #19506] FATAL -- : No code sample named 'SECTION0'. Known samples: helpers, SECTION3, open_with_pipe, open_with_pipe_dash, popen, popen_with_dash, SECTION8 (IndexError)
|
8
|
+
|
9
|
+
<2009-07-12 Sun> My mistake... the shell was interpreting the $SOURCE directive.
|
10
|
+
|
11
|
+
* DONE Make $SOURCE use the actual source file path in processes
|
12
|
+
CLOSED: [2009-07-12 Sun 19:46]
|
13
|
+
|
14
|
+
* DONE Improve error message for non-matching regexen in selectors :usability:
|
15
|
+
CLOSED: [2009-07-13 Mon 02:17]
|
16
|
+
* DONE Make text transforms just another process for pipelines :techdebt:
|
17
|
+
CLOSED: [2009-07-19 Sun 16:33]
|
18
|
+
This should help make [[*Make%20it%20possible%20for%20publishers%20to%20use%20formatted%20text%20as%20input][this item]] possible.
|
19
|
+
* DONE Add standard "select" option to publishers
|
20
|
+
CLOSED: [2009-07-19 Sun 16:33]
|
21
|
+
The select option would define a selector to be used to get the input for the
|
22
|
+
publisher. Another step towards [[*Make%20it%20possible%20for%20publishers%20to%20use%20formatted%20text%20as%20input][this]].
|
23
|
+
|
24
|
+
This MAY make the current "pipeline" option redundant.
|
25
|
+
* DONE Make it possible for publishers to use formatted text as input :feature:
|
26
|
+
CLOSED: [2009-07-19 Sun 16:33]
|
27
|
+
Pretty useless without this...
|
28
|
+
|
29
|
+
* TODO Refactor format command into a null publisher :techdebt:
|
30
|
+
This just needs one last step of pre-loading a "stdout publisher" and then we
|
31
|
+
can do e.g.:
|
32
|
+
|
33
|
+
: germ publish stdout my_article.c
|
34
|
+
* TODO Output line numbers for Reader errors :usability:
|
35
|
+
|
36
|
+
* DONE Gist uploads :feature:
|
37
|
+
CLOSED: [2009-07-21 Tue 10:54]
|
38
|
+
|
39
|
+
* DONE Publishing to WordPress blogs (Atompub) :feature:
|
40
|
+
CLOSED: [2009-07-21 Tue 10:54]
|
41
|
+
|
42
|
+
* TODO Alternate directive syntax :usability:
|
43
|
+
one that doesn't conflict with RDoc
|
44
|
+
|
45
|
+
* TODO Anonymous processes :feature:
|
46
|
+
A process that doesn't match a predefined process name should be interpreted
|
47
|
+
as a shell command.
|
48
|
+
|
49
|
+
* TODO Code indent :feature:
|
50
|
+
Define an indent (either N spaces or a string) to be applied to code sections.
|
51
|
+
|
52
|
+
Should first de-indent code.
|
53
|
+
|
54
|
+
* TODO Shorthand for matching whitespace in selectors :feature:
|
55
|
+
e.g. "@mysample:/def foo/..._"
|
56
|
+
|
57
|
+
* TODO Format Pipelines :feature:
|
58
|
+
Define a pipeline to be run on the entire article after formatting
|
59
|
+
|
60
|
+
Or maybe just demote "format" to be a built-in publisher.
|
61
|
+
* TODO ERB Substitution :feature:
|
62
|
+
Should be run on TEXT sections.
|
63
|
+
|
64
|
+
* TODO Line# Helper :feature:
|
65
|
+
A helper for ERB subtitution which inserts the line# of a given selector.
|
66
|
+
|
67
|
+
* TODO Plugin API :feature:
|
68
|
+
* TODO User-global preference file :feature:
|
69
|
+
|
70
|
+
* TODO Multiple file support :feature:
|
71
|
+
|
72
|
+
* TODO Output line numbers for errors at any point :usability:
|
73
|
+
This will require giving Hunks the knowledge of their source offset.
|
74
|
+
|
75
|
+
* TODO Nested samples :feature:
|
76
|
+
Might want to wait this on the implementation of nested states in AlterEgo.
|
77
|
+
|
78
|
+
* TODO Optionally capture STDERR from processes :feature:
|
79
|
+
|
80
|
+
Workaround: Authors can just include 2>&1 in their process definitions.
|
81
|
+
|
82
|
+
* DONE Syntax for post-process excerpting :feature:
|
83
|
+
CLOSED: [2009-07-12 Sun 20:50]
|
84
|
+
E.g. "$SOURCE|ruby:/---/../---/"
|
85
|
+
|
86
|
+
This would cause the process to be run on $SOURCE and then a subset of the
|
87
|
+
output to be excerpted.
|
88
|
+
|
89
|
+
* TODO Named Styles :feature:
|
90
|
+
A way to group together a bunch of style attributes in a reusable way.
|
91
|
+
* DONE A way to set arbitrary variables for later substitution :feature:
|
92
|
+
CLOSED: [2009-07-16 Thu 11:51]
|
93
|
+
* DONE Standard "pipeline" option for publishers :feature:
|
94
|
+
CLOSED: [2009-07-15 Wed 01:32]
|
95
|
+
Defines a pipeline which will be run on $SOURCE before publishing.
|
96
|
+
* TODO Plugin discovery :feature:
|
97
|
+
Should use gems to discover plugins.
|
98
|
+
|
99
|
+
* TODO Line continuations for directives :usability:
|
100
|
+
After some thought I think what I really want is a second syntax for long-form
|
101
|
+
directives, wherein the YAML arguments go in between directive opening and
|
102
|
+
closing lines. E.g.
|
103
|
+
|
104
|
+
: # :PUBLISHER: ---
|
105
|
+
: # - source
|
106
|
+
: # - shell
|
107
|
+
: # -
|
108
|
+
: # command: cat
|
109
|
+
: # pipeline: markdown
|
110
|
+
: # :END:
|
111
|
+
* DONE Variables
|
112
|
+
CLOSED: [2009-07-16 Thu 19:47]
|
113
|
+
Syntax:
|
114
|
+
: :SET: foo, 123
|
115
|
+
*** Reader records what line they were set on
|
116
|
+
*** SourceFile class which can set and re-set variables
|
117
|
+
- Backs the file up first
|
118
|
+
- Verifies the backup
|
119
|
+
- Locks the file and the backup
|
120
|
+
- Removes the old line
|
121
|
+
- Replaces it with a new :SET: line
|
122
|
+
- Or adds a new :SET: line to the end
|
123
|
+
- Re-reads and verifies value
|
124
|
+
- Restores the backup if there is a problem
|
125
|
+
|
126
|
+
*** Variables are available to processes as environment vars
|
127
|
+
* TODO Add processing/style options to TEXT sections :feature:
|
128
|
+
* TODO Add console modes :feature:
|
129
|
+
*** TODO Shell console
|
130
|
+
In this version we just exec $SHELL with some custom environment. A
|
131
|
+
GERMINATE_SOURCE variable should point to the source file, and all germ
|
132
|
+
commands should use it if no explicit source is specified.
|
133
|
+
|
134
|
+
In addition, aliases for all the common germ modes should be installed -
|
135
|
+
publish, format, list, etc.
|
136
|
+
*** TODO Debug console
|
137
|
+
An IRB session with Germinate preloaded.
|
138
|
+
|
139
|
+
* TODO Clean up output during tests :techdebt:
|
140
|
+
* TODO Add a dry-run mode :feature:
|
data/bin/germ
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(
|
4
|
+
File.join(File.dirname(__FILE__), %w[.. lib germinate]))
|
5
|
+
|
6
|
+
require 'English'
|
7
|
+
require 'main'
|
8
|
+
|
9
|
+
Main do
|
10
|
+
description <<-END
|
11
|
+
Germinate - A tool for writing about code.
|
12
|
+
|
13
|
+
With Germinate, your source code is also your article text. Special
|
14
|
+
directives tell Germinate which parts to format as article text and
|
15
|
+
where to insert source code excerpts and program output.
|
16
|
+
|
17
|
+
To get started, execute:
|
18
|
+
|
19
|
+
germ generate > my_article.rb
|
20
|
+
|
21
|
+
to have Germinate generate a basic example article.
|
22
|
+
|
23
|
+
For more information, see the project homepage at
|
24
|
+
http://github.com/devver/germinate/
|
25
|
+
|
26
|
+
Development of Germinate is graciously sponsored by Devver, purveyor
|
27
|
+
of fine cloud-based services to busy Ruby developers. If you like
|
28
|
+
this tool please check them out at http://devver.net.
|
29
|
+
END
|
30
|
+
|
31
|
+
author "Avdi Grimm <avdi@avdi.org>"
|
32
|
+
|
33
|
+
version Germinate::VERSION
|
34
|
+
|
35
|
+
def self.source_argument
|
36
|
+
argument :source do
|
37
|
+
arity 1
|
38
|
+
validate{|source| Pathname(source).readable?}
|
39
|
+
description "Source file"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
option(:debug, :d) do
|
44
|
+
cast :bool
|
45
|
+
end
|
46
|
+
|
47
|
+
def run
|
48
|
+
help!
|
49
|
+
end
|
50
|
+
|
51
|
+
mode :format do
|
52
|
+
description "Format an article for publishing"
|
53
|
+
source_argument
|
54
|
+
def run
|
55
|
+
with_source_file do |source, path|
|
56
|
+
@application.format(source, path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
mode :list do
|
62
|
+
description "List info about the source file"
|
63
|
+
argument :collection do
|
64
|
+
arity 1
|
65
|
+
required
|
66
|
+
argument_required
|
67
|
+
description "One of: sections, samples, processes, publishers, variables"
|
68
|
+
end
|
69
|
+
source_argument
|
70
|
+
|
71
|
+
def run
|
72
|
+
with_source_file do |source, path|
|
73
|
+
@application.list(source, path, params[:collection].value)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
mode :show do
|
79
|
+
description "Show details about various article components"
|
80
|
+
argument :type do
|
81
|
+
arity 1
|
82
|
+
required
|
83
|
+
argument_required
|
84
|
+
description "One of: section, sample, process, publisher, variable"
|
85
|
+
end
|
86
|
+
argument :item do
|
87
|
+
arity 1
|
88
|
+
required
|
89
|
+
argument_required
|
90
|
+
description "The specific item to show details about"
|
91
|
+
end
|
92
|
+
source_argument
|
93
|
+
|
94
|
+
def run
|
95
|
+
with_source_file do |source, path|
|
96
|
+
@application.show(source, path, params['type'].value, params['item'].value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
mode :select do
|
102
|
+
description "Test out a selector"
|
103
|
+
argument :selector do
|
104
|
+
arity 1
|
105
|
+
required
|
106
|
+
argument_required
|
107
|
+
description "The selector to retrieve"
|
108
|
+
end
|
109
|
+
source_argument
|
110
|
+
|
111
|
+
Germinate::TextTransforms.singleton_methods.each do |transform|
|
112
|
+
option(transform) do
|
113
|
+
description "Enable/disable the '#{transform}' text transform"
|
114
|
+
cast :bool
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def run
|
119
|
+
options = Germinate::TextTransforms.singleton_methods.inject({}) do
|
120
|
+
|opts, transform|
|
121
|
+
if params[transform].given?
|
122
|
+
opts[transform] = params[transform].value
|
123
|
+
logger.info "Text transform '#{transform}' " +
|
124
|
+
(params[transform].value ? "enabled" : "disabled")
|
125
|
+
end
|
126
|
+
opts
|
127
|
+
end
|
128
|
+
with_source_file do |source, path|
|
129
|
+
@application.select(source, path, params[:selector].value, options)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
mode :generate do
|
135
|
+
description "Generate a sample article"
|
136
|
+
|
137
|
+
def run
|
138
|
+
example = File.expand_path("../doc/examples/basic.rb",
|
139
|
+
File.dirname(__FILE__))
|
140
|
+
stdout.write(File.read(example))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
mode :publish do
|
145
|
+
description "Publish the article using the named publisher"
|
146
|
+
argument :publisher
|
147
|
+
source_argument
|
148
|
+
option 'publish-options' do
|
149
|
+
arity 1
|
150
|
+
end
|
151
|
+
|
152
|
+
def run
|
153
|
+
with_source_file do |source, path|
|
154
|
+
options = YAML.load(params['publish-options'].value || "{}")
|
155
|
+
@application.publish(source, path, params[:publisher].value, options)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
mode :set do
|
161
|
+
description "Set a named value in the article"
|
162
|
+
argument :name do
|
163
|
+
description "Variable name"
|
164
|
+
cast :string
|
165
|
+
end
|
166
|
+
argument :value do
|
167
|
+
description "Variable value"
|
168
|
+
cast :string
|
169
|
+
end
|
170
|
+
source_argument
|
171
|
+
|
172
|
+
def run
|
173
|
+
with_source_file do |source, path|
|
174
|
+
@application.set(
|
175
|
+
source,
|
176
|
+
path,
|
177
|
+
params[:name].value,
|
178
|
+
params[:value].value)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def initialize
|
184
|
+
@command = "#{$PROGRAM_NAME} #{ARGV.join(' ')}"
|
185
|
+
Germinate.logger = logger
|
186
|
+
logger.progname = "germinate"
|
187
|
+
logger.formatter = lambda { |severity, time, progname, message|
|
188
|
+
lines = case message
|
189
|
+
when ::String then message.split("\n")
|
190
|
+
when ::Exception then
|
191
|
+
Array(message.message) + Array(message.backtrace)
|
192
|
+
else
|
193
|
+
message.inspect
|
194
|
+
end
|
195
|
+
lines.map{|l| "#{severity} -- #{progname}: #{l}"}.join("\n") + "\n"
|
196
|
+
}
|
197
|
+
@application = Germinate::Application.new(stdout, stderr)
|
198
|
+
@application.load_plugins!
|
199
|
+
end
|
200
|
+
|
201
|
+
def pre_parse_parameters
|
202
|
+
end
|
203
|
+
|
204
|
+
def pre_run
|
205
|
+
logger.level = params['debug'].value ? Logger::DEBUG : Logger::INFO
|
206
|
+
end
|
207
|
+
|
208
|
+
def with_source_file
|
209
|
+
rescue_errors do
|
210
|
+
path = params['source'].value
|
211
|
+
File.open(path) do |file|
|
212
|
+
yield file, path
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def rescue_errors
|
218
|
+
yield
|
219
|
+
rescue RuntimeError => error
|
220
|
+
raise if params['debug'].value
|
221
|
+
log_user_error(error)
|
222
|
+
rescue Exception => error
|
223
|
+
raise if params['debug'].value
|
224
|
+
log_program_error(error)
|
225
|
+
end
|
226
|
+
|
227
|
+
def log_user_error(error)
|
228
|
+
log_fatal_error <<-END
|
229
|
+
Germinate could not complete your command.
|
230
|
+
Please check your command and article for proper syntax.
|
231
|
+
#{command_report}
|
232
|
+
#{error_report(error)}
|
233
|
+
For more information, re-run the command with the --debug flag.
|
234
|
+
END
|
235
|
+
end
|
236
|
+
|
237
|
+
def log_program_error(error)
|
238
|
+
log_fatal_error <<-END
|
239
|
+
Germinate encountered an error while executing your command.
|
240
|
+
#{command_report}
|
241
|
+
#{error_report(error)}
|
242
|
+
Please re-run the command with the --debug flag, and file a problem report at
|
243
|
+
http://github.com/devver/germinate/
|
244
|
+
END
|
245
|
+
end
|
246
|
+
|
247
|
+
def command_report
|
248
|
+
"The command was: '#{@command}'"
|
249
|
+
end
|
250
|
+
|
251
|
+
def error_report(error)
|
252
|
+
"The error was: '#{error.message}'"
|
253
|
+
end
|
254
|
+
|
255
|
+
def log_fatal_error(error)
|
256
|
+
logger.fatal(error)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# EOF
|