germinate 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/.gitignore +2 -0
  2. data/History.txt +26 -0
  3. data/README.rdoc +152 -0
  4. data/Rakefile +43 -0
  5. data/TODO +140 -0
  6. data/bin/germ +260 -0
  7. data/cucumber.yml +2 -0
  8. data/examples/basic.rb +123 -0
  9. data/examples/short.rb +19 -0
  10. data/features/author-formats-article.feature +111 -0
  11. data/features/author-lists-info.pending_feature +48 -0
  12. data/features/author-publishes-article-source.feature +5 -0
  13. data/features/author-publishes-article.feature +57 -0
  14. data/features/author-republishes-article.feature +5 -0
  15. data/features/author-selects-hunks.feature +26 -0
  16. data/features/author-sets-variables.feature +88 -0
  17. data/features/author-updates-article-source.feature +5 -0
  18. data/features/author-views-stuff.pending_feature +52 -0
  19. data/features/bin/quoter +6 -0
  20. data/features/bin/sorter +4 -0
  21. data/features/example_articles/bracketing.rb +27 -0
  22. data/features/example_articles/escaping.txt +13 -0
  23. data/features/example_articles/excerpt_output.rb +16 -0
  24. data/features/example_articles/hello.rb +9 -0
  25. data/features/example_articles/pipelines.txt +25 -0
  26. data/features/example_articles/regexen.rb +24 -0
  27. data/features/example_articles/sample_offsets.rb +18 -0
  28. data/features/example_articles/specials.rb +19 -0
  29. data/features/example_articles/stderr.rb +10 -0
  30. data/features/example_articles/wrapping.rb +8 -0
  31. data/features/example_output/bracketing.out +23 -0
  32. data/features/example_output/code_samples.txt +186 -0
  33. data/features/example_output/escaping.out +5 -0
  34. data/features/example_output/excerpt_output.out +6 -0
  35. data/features/example_output/hello.txt +1 -0
  36. data/features/example_output/pipelines.out +28 -0
  37. data/features/example_output/regexen.txt +22 -0
  38. data/features/example_output/sample_offsets.txt +15 -0
  39. data/features/example_output/specials.txt +40 -0
  40. data/features/example_output/stderr.out +3 -0
  41. data/features/example_output/wrapping.txt +3 -0
  42. data/features/step_definitions/germinate.rb +42 -0
  43. data/features/support/env.rb +20 -0
  44. data/germinate.gemspec +55 -0
  45. data/lib/germinate.rb +54 -0
  46. data/lib/germinate/application.rb +113 -0
  47. data/lib/germinate/article_editor.rb +20 -0
  48. data/lib/germinate/formatter.rb +119 -0
  49. data/lib/germinate/hunk.rb +183 -0
  50. data/lib/germinate/implicit_insertion.rb +9 -0
  51. data/lib/germinate/insertion.rb +29 -0
  52. data/lib/germinate/librarian.rb +293 -0
  53. data/lib/germinate/origin.rb +5 -0
  54. data/lib/germinate/pipeline.rb +13 -0
  55. data/lib/germinate/publisher.rb +57 -0
  56. data/lib/germinate/reader.rb +266 -0
  57. data/lib/germinate/selector.rb +136 -0
  58. data/lib/germinate/shared_style_attributes.rb +54 -0
  59. data/lib/germinate/shell_process.rb +94 -0
  60. data/lib/germinate/shell_publisher.rb +19 -0
  61. data/lib/germinate/simple_publisher.rb +7 -0
  62. data/lib/germinate/source_file.rb +41 -0
  63. data/lib/germinate/text_transforms.rb +119 -0
  64. data/lib/germinate/transform_process.rb +25 -0
  65. data/lib/germinate/variable.rb +23 -0
  66. data/sample.rb +14 -0
  67. data/spec/germinate/application_spec.rb +31 -0
  68. data/spec/germinate/article_editor_spec.rb +97 -0
  69. data/spec/germinate/code_hunk_spec.rb +73 -0
  70. data/spec/germinate/file_hunk_spec.rb +28 -0
  71. data/spec/germinate/formatter_spec.rb +160 -0
  72. data/spec/germinate/hunk_spec.rb +84 -0
  73. data/spec/germinate/implicit_insertion_spec.rb +33 -0
  74. data/spec/germinate/insertion_spec.rb +19 -0
  75. data/spec/germinate/librarian_spec.rb +555 -0
  76. data/spec/germinate/pipeline_spec.rb +34 -0
  77. data/spec/germinate/process_spec.rb +105 -0
  78. data/spec/germinate/publisher_spec.rb +130 -0
  79. data/spec/germinate/reader_spec.rb +385 -0
  80. data/spec/germinate/selector_spec.rb +121 -0
  81. data/spec/germinate/shell_publisher_spec.rb +61 -0
  82. data/spec/germinate/source_file_spec.rb +99 -0
  83. data/spec/germinate/text_hunk_spec.rb +98 -0
  84. data/spec/germinate/text_transforms_spec.rb +242 -0
  85. data/spec/germinate/transform_process_spec.rb +50 -0
  86. data/spec/germinate/variable_spec.rb +14 -0
  87. data/spec/germinate_spec.rb +8 -0
  88. data/spec/spec.opts +1 -0
  89. data/spec/spec_helper.rb +16 -0
  90. data/tasks/ann.rake +80 -0
  91. data/tasks/bones.rake +20 -0
  92. data/tasks/cucumber.rake +5 -0
  93. data/tasks/gem.rake +201 -0
  94. data/tasks/git.rake +40 -0
  95. data/tasks/notes.rake +27 -0
  96. data/tasks/post_load.rake +34 -0
  97. data/tasks/rdoc.rake +51 -0
  98. data/tasks/rubyforge.rake +55 -0
  99. data/tasks/setup.rb +292 -0
  100. data/tasks/spec.rake +54 -0
  101. data/tasks/svn.rake +47 -0
  102. data/tasks/test.rake +40 -0
  103. data/tasks/zentest.rake +36 -0
  104. data/test/test_germinate.rb +0 -0
  105. metadata +228 -0
@@ -0,0 +1,5 @@
1
+ Here are some Germinate directives :TEXT: :SAMPLE: :INSERT: You get the idea.
2
+
3
+ It works in code too:
4
+
5
+ # :PROCESS: foo, bar
@@ -0,0 +1,6 @@
1
+ ===
2
+ line 2
3
+ =====
4
+ ---
5
+ line 1
6
+ -----
@@ -0,0 +1 @@
1
+ Hello, world!
@@ -0,0 +1,28 @@
1
+ Sorting the sample:
2
+ aaron
3
+ george
4
+ joe
5
+ sally
6
+ susan
7
+ zack
8
+
9
+ Quoting the sample:
10
+ > joe
11
+ > sally
12
+ > aaron
13
+ > george
14
+ > zack
15
+ > susan
16
+
17
+ We can combine pipelines with excerpting:
18
+ > sally
19
+ > aaron
20
+ > george
21
+
22
+ And we can chain processes to form a true pipeline:
23
+ > aaron
24
+ > george
25
+ > joe
26
+ > sally
27
+ > susan
28
+ > zack
@@ -0,0 +1,22 @@
1
+ We can select code by regexp
2
+ def foo
3
+ # ...
4
+ end
5
+
6
+ Or with a regex and a length
7
+ def bar
8
+ # ...
9
+ end
10
+
11
+ class Frob
12
+ # ...
13
+ end
14
+
15
+ Ending offset can be exclusive
16
+ def foo
17
+ # ...
18
+ end
19
+
20
+ def bar
21
+ # ...
22
+ end
@@ -0,0 +1,15 @@
1
+ We can specify a starting offset:
2
+ a_line_2 = 2
3
+
4
+ And an ending offset
5
+ a_line_2 = 2
6
+ a_line_3 = 3
7
+
8
+ Ending offset can be exclusive
9
+ a_line_1 = 1
10
+ a_line_2 = 2
11
+
12
+ We can specify offset and count instead
13
+ a_line_2 = 2
14
+ a_line_3 = 3
15
+ a_line_4 = 4
@@ -0,0 +1,40 @@
1
+ We can paste in all the code:
2
+ a_line_1 = 1
3
+ a_line_2 = 2
4
+ a_line_3 = 3
5
+ a_line_4 = 4
6
+
7
+ b_line_1 = 1
8
+ b_line_2 = 2
9
+
10
+
11
+ Or all the text:
12
+ # We can paste in all the code:
13
+ Insertion[$CODE(<Unknown>)]
14
+ #
15
+ # Or all the text:
16
+ Insertion[$TEXT(<Unknown>)]
17
+ #
18
+ # Or the entire source file
19
+ Insertion[$SOURCE(<Unknown>)]
20
+
21
+ Or the entire source file
22
+ # :SAMPLE: A
23
+ a_line_1 = 1
24
+ a_line_2 = 2
25
+ a_line_3 = 3
26
+ a_line_4 = 4
27
+
28
+ # :SAMPLE: B
29
+ b_line_1 = 1
30
+ b_line_2 = 2
31
+
32
+ # :TEXT:
33
+ # We can paste in all the code:
34
+ # :INSERT: $CODE, { disable_transforms: true }
35
+ #
36
+ # Or all the text:
37
+ # :INSERT: $TEXT, { disable_transforms: true }
38
+ #
39
+ # Or the entire source file
40
+ # :INSERT: $SOURCE, { disable_transforms: true }
@@ -0,0 +1,3 @@
1
+ Hello, STDOUT
2
+ Hello, STDERR
3
+ Hello again, STDOUT
@@ -0,0 +1,3 @@
1
+ 'Twas brillig and the slithy toves Did gyre and gimbal in the wabe
2
+
3
+ All mimsy were the borogroves And the momeraths outgrabe
@@ -0,0 +1,42 @@
1
+ require 'tempfile'
2
+
3
+ Given /^the article "([^\"]*)"$/ do |article_file|
4
+ @filename = (EXAMPLE_ARTICLES + article_file)
5
+ end
6
+
7
+ When /^I run the format command on the article$/ do
8
+ run_germinate("format #{@filename}")
9
+ end
10
+
11
+ When /^I run the command "([^\"]*)" on the article$/ do |command|
12
+ run_germinate(command.sub(/^germ /,"") + " #{@filename}")
13
+ end
14
+
15
+ Then /^the output should look like "([^\"]*)"$/ do |output_file|
16
+ example_path = (EXAMPLE_OUTPUT + output_file)
17
+ example_output = example_path.read
18
+ @output.should == example_output
19
+ end
20
+
21
+ Given /^an article with the contents:$/ do |contents|
22
+ file = Tempfile.open("germinate_example_article")
23
+ file.write(contents)
24
+ file.close
25
+ at_exit do
26
+ file.delete
27
+ end
28
+ @filename = Pathname(file.path)
29
+ end
30
+
31
+ Then /^the output should be as follows:$/ do |example_output|
32
+ @output.strip.should == example_output.strip
33
+ end
34
+
35
+ Then /^the article contents should be:$/ do |contents|
36
+ @filename.read.strip.should == contents.strip
37
+ end
38
+
39
+ Then /^the article backup contents should be:$/ do |contents|
40
+ Pathname(@filename.to_s + ".germ.bak").read.should == contents
41
+ end
42
+
@@ -0,0 +1,20 @@
1
+ require 'English'
2
+ require 'pathname'
3
+ require 'spec/expectations'
4
+ require File.expand_path('../../lib/germinate', File.dirname(__FILE__))
5
+
6
+ EXAMPLE_ARTICLES = (Pathname(__FILE__).dirname + '../example_articles')
7
+ EXAMPLE_OUTPUT = (Pathname(__FILE__).dirname + '../example_output')
8
+ EXAMPLE_BIN = (Pathname(__FILE__).dirname + '../bin')
9
+
10
+ ENV['PATH'] += ":" + EXAMPLE_BIN.to_s
11
+
12
+ def run_germinate(arguments, permit_failure=false)
13
+ exec_path = (Pathname(__FILE__).dirname + '..' + '..' + 'bin/germ').expand_path
14
+ command = "#{exec_path} #{arguments}"
15
+ @output = `#{command}`
16
+ @result = $CHILD_STATUS
17
+ raise "Command `#{command}` failed" unless @result.success? or permit_failure
18
+ end
19
+
20
+
@@ -0,0 +1,55 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{germinate}
5
+ s.version = "1.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Avdi Grimm"]
9
+ s.date = %q{2009-07-21}
10
+ s.default_executable = %q{germ}
11
+ s.description = %q{Germinate is a tool for writing about code. With Germinate, the source code IS the article. For example, given the following source code: # #!/usr/bin/env ruby # :BRACKET_CODE: <pre>, </pre> # :PROCESS: ruby, "ruby %f" # :SAMPLE: hello def hello(who) puts "Hello, #{who}" end hello("World") # :TEXT: # Check out my amazing program! Here's the hello method: # :INSERT: @hello:/def/../end/ # And here's the output: # :INSERT: @hello|ruby When we run the <tt>germ format</tt> command the following output is generated: Check out my amazing program! Here's the hello method: <pre> def hello(who) puts "Hello, #{who}" end </pre> And here's the output: <pre> Hello, World </pre> To get a better idea of how this works, please take a look at link:examples/basic.rb, or run: germ generate > basic.rb To generate an example article to play with. Germinate is particularly useful for writing articles, such as blog posts, which contain code excerpts. Instead of forcing you to keep a source code file and an article document in sync throughout the editing process, the Germinate motto is "The source code IS the article". Specially marked comment sections in your code file become the article text. Wherever you need to reference the source code in the article, use insertion directives to tell Germinate what parts of the code to excerpt. An advanced selector syntax enables you to be very specific about which lines of code you want to insert. If you also want to show the output of your code, Germinate has you covered. Special "process" directives enable you to define arbitrary commands which can be run on your code. The output of the command then becomes the excerpt text. You can define an arbitrary number of processes and have different excerpts showing the same code as processed by different commands. You can even string processes together into pipelines. Development of Germinate is graciously sponsored by Devver, purveyor of fine cloud-based services to busy Ruby developers. If you like this tool please check them out at http://devver.net.}
12
+ s.email = %q{avdi@avdi.org}
13
+ s.executables = ["germ"]
14
+ s.extra_rdoc_files = ["History.txt", "README.rdoc", "bin/germ"]
15
+ s.files = [".gitignore", "History.txt", "README.rdoc", "Rakefile", "TODO", "bin/germ", "cucumber.yml", "examples/basic.rb", "examples/short.rb", "features/author-formats-article.feature", "features/author-lists-info.pending_feature", "features/author-publishes-article-source.feature", "features/author-publishes-article.feature", "features/author-republishes-article.feature", "features/author-selects-hunks.feature", "features/author-sets-variables.feature", "features/author-updates-article-source.feature", "features/author-views-stuff.pending_feature", "features/bin/quoter", "features/bin/sorter", "features/example_articles/bracketing.rb", "features/example_articles/escaping.txt", "features/example_articles/excerpt_output.rb", "features/example_articles/hello.rb", "features/example_articles/pipelines.txt", "features/example_articles/regexen.rb", "features/example_articles/sample_offsets.rb", "features/example_articles/specials.rb", "features/example_articles/stderr.rb", "features/example_articles/wrapping.rb", "features/example_output/bracketing.out", "features/example_output/code_samples.txt", "features/example_output/escaping.out", "features/example_output/excerpt_output.out", "features/example_output/hello.txt", "features/example_output/pipelines.out", "features/example_output/regexen.txt", "features/example_output/sample_offsets.txt", "features/example_output/specials.txt", "features/example_output/stderr.out", "features/example_output/wrapping.txt", "features/step_definitions/germinate.rb", "features/support/env.rb", "germinate.gemspec", "lib/germinate.rb", "lib/germinate/application.rb", "lib/germinate/article_editor.rb", "lib/germinate/formatter.rb", "lib/germinate/hunk.rb", "lib/germinate/implicit_insertion.rb", "lib/germinate/insertion.rb", "lib/germinate/librarian.rb", "lib/germinate/origin.rb", "lib/germinate/pipeline.rb", "lib/germinate/publisher.rb", "lib/germinate/reader.rb", "lib/germinate/selector.rb", "lib/germinate/shared_style_attributes.rb", "lib/germinate/shell_process.rb", "lib/germinate/shell_publisher.rb", "lib/germinate/simple_publisher.rb", "lib/germinate/source_file.rb", "lib/germinate/text_transforms.rb", "lib/germinate/transform_process.rb", "lib/germinate/variable.rb", "sample.rb", "spec/germinate/application_spec.rb", "spec/germinate/article_editor_spec.rb", "spec/germinate/code_hunk_spec.rb", "spec/germinate/file_hunk_spec.rb", "spec/germinate/formatter_spec.rb", "spec/germinate/hunk_spec.rb", "spec/germinate/implicit_insertion_spec.rb", "spec/germinate/insertion_spec.rb", "spec/germinate/librarian_spec.rb", "spec/germinate/pipeline_spec.rb", "spec/germinate/process_spec.rb", "spec/germinate/publisher_spec.rb", "spec/germinate/reader_spec.rb", "spec/germinate/selector_spec.rb", "spec/germinate/shell_publisher_spec.rb", "spec/germinate/source_file_spec.rb", "spec/germinate/text_hunk_spec.rb", "spec/germinate/text_transforms_spec.rb", "spec/germinate/transform_process_spec.rb", "spec/germinate/variable_spec.rb", "spec/germinate_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/ann.rake", "tasks/bones.rake", "tasks/cucumber.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/notes.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/spec.rake", "tasks/svn.rake", "tasks/test.rake", "tasks/zentest.rake", "test/test_germinate.rb"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/devver/germinate/}
18
+ s.rdoc_options = ["--main", "README.rdoc"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{germinate}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{Germinate is a tool for writing about code}
23
+ s.test_files = ["test/test_germinate.rb"]
24
+
25
+ if s.respond_to? :specification_version then
26
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
+ s.specification_version = 2
28
+
29
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ s.add_runtime_dependency(%q<ick>, ["~> 0.3.0"])
31
+ s.add_runtime_dependency(%q<fattr>, ["~> 1.0.3"])
32
+ s.add_runtime_dependency(%q<arrayfields>, ["~> 4.7.3"])
33
+ s.add_runtime_dependency(%q<orderedhash>, ["~> 0.0.6"])
34
+ s.add_runtime_dependency(%q<alter-ego>, ["~> 1.0.0"])
35
+ s.add_runtime_dependency(%q<main>, ["~> 2.8.3"])
36
+ s.add_development_dependency(%q<bones>, [">= 2.5.1"])
37
+ else
38
+ s.add_dependency(%q<ick>, ["~> 0.3.0"])
39
+ s.add_dependency(%q<fattr>, ["~> 1.0.3"])
40
+ s.add_dependency(%q<arrayfields>, ["~> 4.7.3"])
41
+ s.add_dependency(%q<orderedhash>, ["~> 0.0.6"])
42
+ s.add_dependency(%q<alter-ego>, ["~> 1.0.0"])
43
+ s.add_dependency(%q<main>, ["~> 2.8.3"])
44
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
45
+ end
46
+ else
47
+ s.add_dependency(%q<ick>, ["~> 0.3.0"])
48
+ s.add_dependency(%q<fattr>, ["~> 1.0.3"])
49
+ s.add_dependency(%q<arrayfields>, ["~> 4.7.3"])
50
+ s.add_dependency(%q<orderedhash>, ["~> 0.0.6"])
51
+ s.add_dependency(%q<alter-ego>, ["~> 1.0.0"])
52
+ s.add_dependency(%q<main>, ["~> 2.8.3"])
53
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
54
+ end
55
+ end
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'fattr'
3
+ require 'logger'
4
+
5
+ module Germinate
6
+
7
+ # :stopdoc:
8
+ VERSION = '1.2.0'
9
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
+ # :startdoc:
12
+
13
+ # Returns the version string for the library.
14
+ #
15
+ def self.version
16
+ VERSION
17
+ end
18
+
19
+ # Returns the library path for the module. If any arguments are given,
20
+ # they will be joined to the end of the libray path using
21
+ # <tt>File.join</tt>.
22
+ #
23
+ def self.libpath( *args )
24
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
25
+ end
26
+
27
+ # Returns the lpath for the module. If any arguments are given,
28
+ # they will be joined to the end of the path using
29
+ # <tt>File.join</tt>.
30
+ #
31
+ def self.path( *args )
32
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
33
+ end
34
+
35
+ # Utility method used to require all files ending in .rb that lie in the
36
+ # directory below this file that has the same name as the filename passed
37
+ # in. Optionally, a specific _directory_ name can be passed in such that
38
+ # the _filename_ does not have to be equivalent to the directory.
39
+ #
40
+ def self.require_all_libs_relative_to( fname, dir = nil )
41
+ dir ||= ::File.basename(fname, '.*')
42
+ search_me = ::File.expand_path(
43
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
44
+
45
+ Dir.glob(search_me).sort.each {|rb| require rb}
46
+ end
47
+
48
+ Fattr(:logger) { Logger.new($stderr) }
49
+
50
+ end # module Germinate
51
+
52
+ Germinate.require_all_libs_relative_to(__FILE__)
53
+
54
+ # EOF
@@ -0,0 +1,113 @@
1
+ require 'English'
2
+
3
+ # The Application ties all the other componts together. It has public methods
4
+ # roughly corresponding commands that the 'germ' command-line tool supports.
5
+ class Germinate::Application
6
+ attr_writer :formatter
7
+
8
+ def initialize(output, errors)
9
+ @output = output
10
+ @error_output = errors
11
+ @log = Germinate.logger
12
+ @plugins = []
13
+ end
14
+
15
+ # Search Rubygems for Germinate plugins and load them
16
+ def load_plugins!
17
+ $LOAD_PATH.each do |dir|
18
+ plugin_init = Pathname(dir) + 'germinate_plugin_v0_init.rb'
19
+ if plugin_init.readable?
20
+ load_plugin!(plugin_init.to_s)
21
+ end
22
+ end
23
+ Gem.find_files('germinate_plugin_v0_init').each do |file|
24
+ load_plugin!(file)
25
+ end
26
+ end
27
+
28
+ def format(source, path)
29
+ librarian = load_librarian(source, path)
30
+ publisher = Germinate::SimplePublisher.new("simple", librarian)
31
+ publisher.publish!(@output)
32
+ end
33
+
34
+ def list(source, path, collection)
35
+ librarian = load_librarian(source, path)
36
+ case collection
37
+ when "sections"
38
+ @output.puts(librarian.section_names.join("\n"))
39
+ when "samples"
40
+ @output.puts(librarian.sample_names.join("\n"))
41
+ when "processes"
42
+ @output.puts(librarian.process_names.join("\n"))
43
+ when "publishers"
44
+ @output.puts(*librarian.publisher_names)
45
+ when "all_publishers"
46
+ Germinate::Publisher.registered_publishers.keys do |p|
47
+ @output.puts(p)
48
+ end
49
+ when "variables"
50
+ librarian.variables.each_pair do |name, value|
51
+ @output.puts("%-20s %s" % [name, value.to_s])
52
+ end
53
+ when "plugins"
54
+ @plugins.each do |plugin|
55
+ puts(plugin)
56
+ end
57
+ else
58
+ raise "I don't know how to list '#{collection}'"
59
+ end
60
+ end
61
+
62
+ def show(source, path, item_type, item)
63
+ librarian = load_librarian(source, path)
64
+ case item_type
65
+ when "section"
66
+ @output.puts(librarian.section(item))
67
+ when "sample"
68
+ @output.puts(librarian.sample(item))
69
+ when "process"
70
+ @output.puts(librarian.process(item).command)
71
+ when "publisher"
72
+ @output.puts(librarian.publisher(item))
73
+ else
74
+ raise "I don't know how to show '#{item_type}'"
75
+ end
76
+ end
77
+
78
+ def select(source, path, selector, options, origin="command line")
79
+ librarian = load_librarian(source, path)
80
+ @output.puts(*librarian[selector, origin, options])
81
+ end
82
+
83
+ def publish(source, path, publisher, options={})
84
+ librarian = load_librarian(source, path)
85
+ librarian.publisher(publisher).publish!(@output, options)
86
+ librarian.store_changes!
87
+ end
88
+
89
+ def set(source, path, name, value)
90
+ librarian = load_librarian(source, path)
91
+ librarian.variables[name] = value
92
+ librarian.store_changes!
93
+ end
94
+
95
+ private
96
+
97
+ def load_librarian(source, path)
98
+ librarian = Germinate::Librarian.new
99
+ reader = Germinate::Reader.new(librarian, path)
100
+ source.each_line do |line|
101
+ reader << line
102
+ end
103
+ librarian
104
+ end
105
+
106
+ def load_plugin!(file)
107
+ unless @plugins.include?(file)
108
+ @log.debug "Loading plugin: #{file}"
109
+ Kernel.load(file)
110
+ @plugins << File.dirname(file)
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,20 @@
1
+ # An Editor is responsible for selecting hunks of text from a Librarian and
2
+ # assembling them into a list for formatting.
3
+ class Germinate::ArticleEditor
4
+ def initialize(librarian)
5
+ @librarian = librarian
6
+ end
7
+
8
+ def each_hunk(&block)
9
+ librarian.section_names.each do |section_name|
10
+ yield librarian.section(section_name).resolve_insertions
11
+ if librarian.has_sample?(section_name)
12
+ yield librarian.sample(section_name).resolve_insertions
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :librarian
20
+ end