devver-germinate 1.0.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.
Files changed (86) hide show
  1. data/.gitignore +2 -0
  2. data/History.txt +4 -0
  3. data/README.rdoc +132 -0
  4. data/Rakefile +43 -0
  5. data/bin/germ +133 -0
  6. data/cucumber.yml +2 -0
  7. data/examples/basic.rb +118 -0
  8. data/examples/short.rb +17 -0
  9. data/features/author-formats-article.feature +108 -0
  10. data/features/author-lists-info.feature +45 -0
  11. data/features/author-publishes-article-source.feature +5 -0
  12. data/features/author-publishes-article.feature +5 -0
  13. data/features/author-republishes-article.feature +5 -0
  14. data/features/author-selects-hunks.feature +26 -0
  15. data/features/author-updates-article-source.feature +5 -0
  16. data/features/author-views-stuff.feature +48 -0
  17. data/features/bin/quoter +6 -0
  18. data/features/bin/sorter +4 -0
  19. data/features/example_articles/code_samples.rb +89 -0
  20. data/features/example_articles/escaping.txt +12 -0
  21. data/features/example_articles/hello.rb +9 -0
  22. data/features/example_articles/pipelines.txt +25 -0
  23. data/features/example_articles/regexen.rb +24 -0
  24. data/features/example_articles/sample_offsets.rb +18 -0
  25. data/features/example_articles/specials.rb +19 -0
  26. data/features/example_articles/wrapping.rb +8 -0
  27. data/features/example_output/code_samples.txt +186 -0
  28. data/features/example_output/escaping.out +5 -0
  29. data/features/example_output/hello.txt +1 -0
  30. data/features/example_output/pipelines.out +28 -0
  31. data/features/example_output/regexen.txt +22 -0
  32. data/features/example_output/sample_offsets.txt +15 -0
  33. data/features/example_output/specials.txt +36 -0
  34. data/features/example_output/wrapping.txt +3 -0
  35. data/features/step_definitions/germinate.rb +30 -0
  36. data/features/support/env.rb +18 -0
  37. data/germinate.gemspec +55 -0
  38. data/lib/germinate.rb +54 -0
  39. data/lib/germinate/application.rb +62 -0
  40. data/lib/germinate/article_editor.rb +20 -0
  41. data/lib/germinate/article_formatter.rb +75 -0
  42. data/lib/germinate/formatter.rb +119 -0
  43. data/lib/germinate/hunk.rb +149 -0
  44. data/lib/germinate/implicit_insertion.rb +9 -0
  45. data/lib/germinate/insertion.rb +15 -0
  46. data/lib/germinate/librarian.rb +179 -0
  47. data/lib/germinate/pipeline.rb +11 -0
  48. data/lib/germinate/process.rb +67 -0
  49. data/lib/germinate/reader.rb +212 -0
  50. data/lib/germinate/selector.rb +95 -0
  51. data/lib/germinate/shared_style_attributes.rb +23 -0
  52. data/lib/germinate/text_transforms.rb +90 -0
  53. data/spec/germinate/application_spec.rb +14 -0
  54. data/spec/germinate/article_editor_spec.rb +97 -0
  55. data/spec/germinate/article_formatter_spec.rb +153 -0
  56. data/spec/germinate/code_hunk_spec.rb +45 -0
  57. data/spec/germinate/formatter_spec.rb +160 -0
  58. data/spec/germinate/hunk_spec.rb +77 -0
  59. data/spec/germinate/implicit_insertion_spec.rb +33 -0
  60. data/spec/germinate/insertion_spec.rb +18 -0
  61. data/spec/germinate/librarian_spec.rb +336 -0
  62. data/spec/germinate/pipeline_spec.rb +24 -0
  63. data/spec/germinate/process_spec.rb +64 -0
  64. data/spec/germinate/reader_spec.rb +306 -0
  65. data/spec/germinate/selector_spec.rb +65 -0
  66. data/spec/germinate/text_hunk_spec.rb +53 -0
  67. data/spec/germinate/text_transforms_spec.rb +154 -0
  68. data/spec/germinate_spec.rb +8 -0
  69. data/spec/spec.opts +1 -0
  70. data/spec/spec_helper.rb +16 -0
  71. data/tasks/ann.rake +80 -0
  72. data/tasks/bones.rake +20 -0
  73. data/tasks/cucumber.rake +5 -0
  74. data/tasks/gem.rake +201 -0
  75. data/tasks/git.rake +40 -0
  76. data/tasks/notes.rake +27 -0
  77. data/tasks/post_load.rake +34 -0
  78. data/tasks/rdoc.rake +51 -0
  79. data/tasks/rubyforge.rake +55 -0
  80. data/tasks/setup.rb +292 -0
  81. data/tasks/spec.rake +54 -0
  82. data/tasks/svn.rake +47 -0
  83. data/tasks/test.rake +40 -0
  84. data/tasks/zentest.rake +36 -0
  85. data/test/test_germinate.rb +0 -0
  86. metadata +209 -0
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ doc
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2009-07-06
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
data/README.rdoc ADDED
@@ -0,0 +1,132 @@
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
+ == FEATURES
78
+
79
+ * Language and markup agnostic
80
+ * Advanced selector syntax for excerpting code
81
+ * Define arbitrary command pipelines to preprocess excerpts
82
+ * Article text is reformatted to be more compatible with popular blogging
83
+ engines, e.g. WordPress.
84
+ * Introspection commands make it easy to experiment
85
+ * Fully tested
86
+
87
+ == KNOWN ISSUES
88
+
89
+ * Directive syntax conflicts with RDoc. Doh!
90
+
91
+ == FUTURE
92
+
93
+ * Integration with blogging platforms, e.g. WordPress
94
+ * Integration with Github's Gist
95
+
96
+ == REQUIREMENTS
97
+
98
+ * main
99
+ * fattr
100
+ * ick
101
+ * orderedhash
102
+ * arrayfields
103
+ * alter-ego
104
+
105
+ == INSTALL:
106
+
107
+ gem install --source http://gems.rubyforge.org devver-germinate
108
+
109
+ == LICENSE:
110
+
111
+ (The MIT License)
112
+
113
+ Copyright (c) 2008
114
+
115
+ Permission is hereby granted, free of charge, to any person obtaining
116
+ a copy of this software and associated documentation files (the
117
+ 'Software'), to deal in the Software without restriction, including
118
+ without limitation the rights to use, copy, modify, merge, publish,
119
+ distribute, sublicense, and/or sell copies of the Software, and to
120
+ permit persons to whom the Software is furnished to do so, subject to
121
+ the following conditions:
122
+
123
+ The above copyright notice and this permission notice shall be
124
+ included in all copies or substantial portions of the Software.
125
+
126
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
127
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
128
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
129
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
130
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
131
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
132
+ 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/bin/germ ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib germinate]))
5
+
6
+ require 'main'
7
+
8
+ Main do
9
+ description <<-END
10
+ Germinate - A tool for writing about code.
11
+
12
+ With Germinate, your source code is also your article text. Special
13
+ directives tell Germinate which parts to format as article text and
14
+ where to insert source code excerpts and program output.
15
+
16
+ To get started, execute:
17
+
18
+ germ generate > my_article.rb
19
+
20
+ to have Germinate generate a basic example article.
21
+
22
+ For more information, see the project homepage at
23
+ http://github.com/devver/germinate/
24
+
25
+ Development of Germinate is graciously sponsored by Devver, purveyor
26
+ of fine cloud-based services to busy Ruby developers. If you like
27
+ this tool please check them out at http://devver.net.
28
+ END
29
+
30
+ author "Avdi Grimm <avdi@avdi.org>"
31
+
32
+ version Germinate::VERSION
33
+
34
+ def self.source_argument
35
+ argument :source do
36
+ arity 1
37
+ validate{|source| Pathname(source).readable?}
38
+ description "Source file"
39
+ end
40
+ end
41
+
42
+ mode :format do
43
+ description "Format an article for publishing"
44
+ source_argument
45
+ def run
46
+ Germinate.logger = self
47
+ with_source_file do |source|
48
+ application = Germinate::Application.new
49
+ application.format(source, $stdout, $stderr)
50
+ end
51
+ end
52
+ end
53
+
54
+ mode :list do
55
+ description "List various article components"
56
+ source_argument
57
+ COLLECTIONS = [:sections, :samples, :processes]
58
+ COLLECTIONS.each do |collection|
59
+ option collection do
60
+ description "List all #{collection}"
61
+ cast :bool
62
+ end
63
+ end
64
+
65
+ def run
66
+ things_to_list = []
67
+ COLLECTIONS.each do |collection|
68
+ things_to_list << collection if params[collection].value
69
+ end
70
+ with_source_file do |source|
71
+ application = Germinate::Application.new
72
+ application.list(source, things_to_list, $stdout)
73
+ end
74
+ end
75
+ end
76
+
77
+ mode :show do
78
+ description "Show details about various article components"
79
+ source_argument
80
+ TYPES = [:section, :sample, :process]
81
+ TYPES.each do |type|
82
+ option type do
83
+ description "Show details about a #{type}"
84
+ argument_required
85
+ end
86
+ end
87
+
88
+ def run
89
+ selection = TYPES.inject({}) {|sel, type|
90
+ sel[type] = params[type].values
91
+ sel
92
+ }
93
+ with_source_file do |source|
94
+ application = Germinate::Application.new
95
+ application.show(source, selection, $stdout)
96
+ end
97
+ end
98
+ end
99
+
100
+ mode :select do
101
+ description "Test out a selector"
102
+ source_argument
103
+ option(:selector, :s) do
104
+ arity 1
105
+ required
106
+ argument_required
107
+ description "The selector to search for"
108
+ end
109
+
110
+ def run
111
+ with_source_file do |source|
112
+ application = Germinate::Application.new
113
+ application.select(source, params[:selector].value, $stdout)
114
+ end
115
+ end
116
+ end
117
+
118
+ mode :generate do
119
+ description "Generate a sample article"
120
+
121
+ def run
122
+ example = File.expand_path("../doc/examples/basic.rb",
123
+ File.dirname(__FILE__))
124
+ stdout.write(File.read(example))
125
+ end
126
+ end
127
+
128
+ def with_source_file(&block)
129
+ File.open(params['source'].value, &block)
130
+ end
131
+ end
132
+
133
+ # EOF
data/cucumber.yml ADDED
@@ -0,0 +1,2 @@
1
+ autotest: --no-color --format pretty
2
+ autotest-all: --no-color --format pretty
data/examples/basic.rb ADDED
@@ -0,0 +1,118 @@
1
+ # A basic example of a Germinate article.
2
+ #
3
+ # This text is "front matter" and will not be included in the final article.
4
+ # The article doesn't begin until the first text directive.
5
+ #
6
+ # Let's set up code bracketing so that code excerpts will be surrounded by HTML
7
+ # <pre>...</pre> tags.
8
+ #
9
+ # :BRACKET_CODE: <pre>, </pre>
10
+ #
11
+ # :TEXT:
12
+ # This is the first line of the article text. For the formatted article,
13
+ # Germinate will remove the comment prefixes ("# ") and join paragraphs into
14
+ # single lines.
15
+ #
16
+ # We're coming up on our first code section. If some code immediately follows a
17
+ # text section it will automatically be inserted into the formatted article
18
+ # text.
19
+ def my_func
20
+ # ...
21
+ end
22
+ # :END:
23
+ #
24
+ # The END directive above ends that particular code sample. This text will not
25
+ # be included in the final article.
26
+ #
27
+ # We don't want to have to write our source code in the order it appears in
28
+ # the article. Let's define a named code sample.
29
+ #
30
+ # :SAMPLE: hello
31
+ def hello
32
+ puts "Hello, #{ARGV[0]}"
33
+ end
34
+ hello
35
+
36
+ # :TEXT:
37
+ # We're back in the article text now. Let's insert our named sample now.
38
+ # :INSERT: @hello
39
+ #
40
+ # Now lets define some processes and experiment with running the sample through
41
+ # them.
42
+ #
43
+ # :PROCESS: fred, "ruby %f Fred"
44
+ # :PROCESS: jane, "ruby %f Jane"
45
+ # :PROCESS: quote, "ruby -n -e 'puts \"> #{$_}\"'"
46
+ #
47
+ # Note that the "quote" process has no %f placeholder for the filename.
48
+ # If it doesn't find a %f, Germinate will pipe the source sample into the
49
+ # command on its STDIN.
50
+ #
51
+ # Here's the result of \:INSERT: @hello|fred
52
+ # :INSERT: @hello|fred
53
+ #
54
+ # Here's the result of :INSERT: @hello|jane
55
+ # :INSERT: @hello|jane
56
+ #
57
+ # We can even chain processes together. Here's the result of
58
+ # \:INSERT: @hello|jane|quote
59
+ # :INSERT: @hello|jane|quote
60
+ #
61
+ # It's not necessary to quote whole code samples. We can select specific lines
62
+ # to excerpt using more advanced selectors.
63
+ #
64
+ # Select a single line
65
+ # \:INSERT: @foo:2
66
+ # :INSERT: @foo:2
67
+ #
68
+ # Select an inclusive range
69
+ # \:INSERT: @foo:2..4
70
+ # :INSERT: @foo:2..4
71
+ #
72
+ # Select an exclusive range
73
+ # \:INSERT: @foo:1...3
74
+ # :INSERT: @foo:1...3
75
+ #
76
+ # Select by starting line and length
77
+ # \:INSERT: @foo:4,4
78
+ # :INSERT: @foo:4,4
79
+ #
80
+ # Select by starting and ending regular expressions
81
+ # \:INSERT: @foo:/do_stuff/../end/
82
+ # :INSERT: @foo:/do_stuff/../end/
83
+ #
84
+ # Select by regex and length
85
+ # \:INSERT: @foo:/attr_reader/,3
86
+ # :INSERT: @foo:/attr_reader/,3
87
+ #
88
+ # :SAMPLE: foo
89
+ class Foo
90
+ attr_reader :bar
91
+ attr_reader :baz
92
+ attr_reader :buz
93
+
94
+ def do_stuff
95
+ # ...
96
+ end
97
+ end
98
+ # :END:
99
+
100
+ # :TEXT:
101
+ # Finally, we can include all of the code samples in a single chunk with
102
+ # \:INSERT: $CODE
103
+ # :INSERT: $CODE
104
+ #
105
+ # There are some other special section names, such as $SOURCE and $TEXT. See
106
+ # the Germinate documentation for more.
107
+ #
108
+ # :CUT:
109
+ #
110
+ # You can format this article for publishing by running:
111
+ #
112
+ # germ format <filename>
113
+ #
114
+ # If you want to experiment with the selector syntax, try:
115
+ #
116
+ # germ select -s <selector>
117
+ #
118
+ # Enjoy!
data/examples/short.rb ADDED
@@ -0,0 +1,17 @@
1
+ # #!/usr/bin/env ruby
2
+ # :BRACKET_CODE: <pre>, </pre>
3
+ # :PROCESS: ruby, "ruby %f"
4
+
5
+ # :SAMPLE: hello
6
+ def hello(who)
7
+ puts "Hello, #{who}"
8
+ end
9
+
10
+ hello("World")
11
+
12
+ # :TEXT:
13
+ # Check out my amazing program! Here's the hello method:
14
+ # :INSERT: @hello:/def/../end/
15
+
16
+ # And here's the output:
17
+ # :INSERT: @hello|ruby