git-scribe 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/.gitignore +1 -0
  2. data/Rakefile +31 -0
  3. data/SPEC.asciidoc +126 -0
  4. data/TODO.txt +29 -0
  5. data/bin/git-scribe +2 -1
  6. data/docbook-xsl/.CatalogManager.properties.example +61 -0
  7. data/docbook-xsl/.urilist +1 -0
  8. data/git-scribe.gemspec +32 -0
  9. data/lib/git-scribe.rb +21 -315
  10. data/lib/git-scribe/check.rb +60 -0
  11. data/lib/git-scribe/cli.rb +84 -0
  12. data/lib/git-scribe/generate.rb +222 -0
  13. data/lib/git-scribe/init.rb +16 -0
  14. data/lib/git-scribe/version.rb +3 -0
  15. data/template/.gitignore +1 -0
  16. data/template/.gitscribe +5 -0
  17. data/test/check_test.rb +12 -0
  18. data/test/gen_test.rb +78 -0
  19. data/test/init_test.rb +36 -0
  20. data/test/test_helper.rb +44 -0
  21. metadata +49 -161
  22. data/example/book/big.asc +0 -5604
  23. data/example/book/holmes.asc +0 -12983
  24. data/example/output/META-INF/container.xml +0 -6
  25. data/example/output/OEBPS/ar01s02.html +0 -15
  26. data/example/output/OEBPS/ar01s03.html +0 -3
  27. data/example/output/OEBPS/content.opf +0 -21
  28. data/example/output/OEBPS/index.html +0 -5
  29. data/example/output/OEBPS/toc.ncx +0 -37
  30. data/example/output/a_case_of_identity.html +0 -725
  31. data/example/output/a_example_appendix.html +0 -63
  32. data/example/output/a_migration_notes.html +0 -95
  33. data/example/output/apa.html +0 -20
  34. data/example/output/apb.html +0 -6
  35. data/example/output/apc.html +0 -24
  36. data/example/output/apd.html +0 -30
  37. data/example/output/ape.html +0 -26
  38. data/example/output/apf.html +0 -9
  39. data/example/output/apg.html +0 -42
  40. data/example/output/aph.html +0 -89
  41. data/example/output/ar01s02.html +0 -12
  42. data/example/output/ar01s03.html +0 -34
  43. data/example/output/ar01s04.html +0 -77
  44. data/example/output/ar01s05.html +0 -272
  45. data/example/output/ar01s06.html +0 -35
  46. data/example/output/ar01s07.html +0 -105
  47. data/example/output/ar01s08.html +0 -33
  48. data/example/output/ar01s09.html +0 -12
  49. data/example/output/ar01s10.html +0 -14
  50. data/example/output/ar01s11.html +0 -34
  51. data/example/output/ar01s12.html +0 -63
  52. data/example/output/ar01s13.html +0 -156
  53. data/example/output/ar01s14.html +0 -330
  54. data/example/output/ar01s15.html +0 -22
  55. data/example/output/ar01s16.html +0 -27
  56. data/example/output/ar01s17.html +0 -94
  57. data/example/output/ar01s18.html +0 -359
  58. data/example/output/ar01s19.html +0 -373
  59. data/example/output/ar01s20.html +0 -27
  60. data/example/output/ar01s21.html +0 -33
  61. data/example/output/ar01s22.html +0 -351
  62. data/example/output/ar01s23.html +0 -21
  63. data/example/output/ar01s24.html +0 -69
  64. data/example/output/ar01s25.html +0 -60
  65. data/example/output/ar01s26.html +0 -217
  66. data/example/output/ar01s27.html +0 -88
  67. data/example/output/ar01s28.html +0 -237
  68. data/example/output/ar01s29.html +0 -68
  69. data/example/output/ar01s30.html +0 -154
  70. data/example/output/ar01s31.html +0 -6
  71. data/example/output/ar01s32.html +0 -22
  72. data/example/output/ar01s33.html +0 -209
  73. data/example/output/asciidoc_backends.html +0 -190
  74. data/example/output/asciidoc_document_types.html +0 -131
  75. data/example/output/attribute_entries.html +0 -185
  76. data/example/output/attribute_lists.html +0 -157
  77. data/example/output/attribute_references.html +0 -414
  78. data/example/output/attributelist_element.html +0 -143
  79. data/example/output/b_packager_notes.html +0 -68
  80. data/example/output/bi01.html +0 -18
  81. data/example/output/big.asc +0 -5604
  82. data/example/output/block_element_definitions.html +0 -448
  83. data/example/output/block_titles.html +0 -83
  84. data/example/output/blockid_element.html +0 -80
  85. data/example/output/book.asc +0 -5604
  86. data/example/output/book.epub +0 -0
  87. data/example/output/book.fo +0 -3788
  88. data/example/output/book.html +0 -8793
  89. data/example/output/book.xml +0 -8265
  90. data/example/output/c_asciidoc_safe_mode.html +0 -105
  91. data/example/output/callouts.html +0 -214
  92. data/example/output/catalog +0 -10
  93. data/example/output/colophon.html +0 -397
  94. data/example/output/configuration_files.html +0 -672
  95. data/example/output/converting_docbook_to_other_file_formats.html +0 -324
  96. data/example/output/d_using_asciidoc_with_non-english_languages.html +0 -107
  97. data/example/output/delimited_blocks.html +0 -455
  98. data/example/output/document_attributes.html +0 -95
  99. data/example/output/document_processing.html +0 -116
  100. data/example/output/document_structure.html +0 -493
  101. data/example/output/e_vim_syntax_highlighter.html +0 -111
  102. data/example/output/example_bibliography.html +0 -82
  103. data/example/output/example_colophon.html +0 -58
  104. data/example/output/example_glossary.html +0 -73
  105. data/example/output/example_index.html +0 -108
  106. data/example/output/f_attribute_options.html +0 -129
  107. data/example/output/filters.html +0 -179
  108. data/example/output/footnotes.html +0 -103
  109. data/example/output/g_diagnostics.html +0 -148
  110. data/example/output/generating_plain_text_files.html +0 -68
  111. data/example/output/getting_started.html +0 -87
  112. data/example/output/glossary.html +0 -95
  113. data/example/output/go01.html +0 -24
  114. data/example/output/h_backend_attributes.html +0 -308
  115. data/example/output/help_commands.html +0 -96
  116. data/example/output/holmes.asc +0 -12983
  117. data/example/output/image/octocat_professor.png +0 -0
  118. data/example/output/include/hello.c +0 -10
  119. data/example/output/index.html +0 -656
  120. data/example/output/indexes.html +0 -104
  121. data/example/output/intrinsic_attributes.html +0 -165
  122. data/example/output/ix01.html +0 -3
  123. data/example/output/lists.html +0 -666
  124. data/example/output/macros.html +0 -737
  125. data/example/output/manpage_documents.html +0 -124
  126. data/example/output/master.css +0 -281
  127. data/example/output/mathematical_formulas.html +0 -125
  128. data/example/output/page.html +0 -60
  129. data/example/output/paragraphs.html +0 -192
  130. data/example/output/pr01.html +0 -3
  131. data/example/output/source_code_highlighting.html +0 -59
  132. data/example/output/stylesheets/handbookish-quirks.css +0 -0
  133. data/example/output/stylesheets/handbookish.css +0 -233
  134. data/example/output/tables.html +0 -797
  135. data/example/output/text_formatting.html +0 -273
  136. data/example/output/the_adventure_of_the_beryl_coronet.html +0 -968
  137. data/example/output/the_adventure_of_the_blue_carbuncle.html +0 -825
  138. data/example/output/the_adventure_of_the_copper_beeches.html +0 -998
  139. data/example/output/the_adventure_of_the_engineer_s_thumb.html +0 -851
  140. data/example/output/the_adventure_of_the_noble_bachelor.html +0 -861
  141. data/example/output/the_adventure_of_the_speckled_band.html +0 -1015
  142. data/example/output/the_boscombe_valley_mystery.html +0 -974
  143. data/example/output/the_first_chapter.html +0 -110
  144. data/example/output/the_five_orange_pips.html +0 -776
  145. data/example/output/the_man_with_the_twisted_lip.html +0 -946
  146. data/example/output/the_red-headed_league.html +0 -950
  147. data/example/output/the_second_chapter.html +0 -95
  148. data/example/output/the_third_chapter.html +0 -58
  149. data/example/output/tips_and_tricks.html +0 -452
  150. data/example/output/title.html +0 -120
  151. data/example/output/titles.html +0 -126
@@ -0,0 +1,60 @@
1
+ class GitScribe
2
+ module Check
3
+ # check that we have everything needed
4
+ def check(args = [])
5
+ status = {}
6
+
7
+ # check for git
8
+ if !check_can_run('git --version')
9
+ info "git is not present, please install it for anything to work"
10
+ status[:git] = true
11
+ else
12
+ info "git - ok"
13
+ status[:git] = false
14
+ end
15
+
16
+ # check for asciidoc
17
+ if !check_can_run('asciidoc')
18
+ info "asciidoc is not present, please install it for anything to work"
19
+ status[:asciidoc] = true
20
+ else
21
+ info "asciidoc - ok"
22
+ status[:asciidoc] = false
23
+ end
24
+
25
+ # check for xsltproc
26
+ if !check_can_run('xsltproc --version')
27
+ info "xsltproc is not present, please install it for html generation"
28
+ status[:xsltproc] = true
29
+ else
30
+ info "xsltproc - ok"
31
+ status[:xsltproc] = false
32
+ end
33
+
34
+ # check for a2x - should be installed with asciidoc, but you never know
35
+ if !check_can_run('a2x')
36
+ info "a2x is not present, please install it for epub generation"
37
+ status[:a2x] = true
38
+ else
39
+ info "a2x - ok"
40
+ status[:a2x] = false
41
+ end
42
+
43
+ # check for fop
44
+ if !check_can_run('fop -version')
45
+ info "fop is not present, please install for PDF generation"
46
+ status[:fop] = true
47
+ else
48
+ info "fop - ok"
49
+ status[:fop] = false
50
+ end
51
+
52
+ status
53
+ end
54
+
55
+ def check_can_run(command)
56
+ `#{command} 2>&1`
57
+ $?.exitstatus == 0
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,84 @@
1
+ require 'subcommand'
2
+
3
+ class GitScribe
4
+ include Subcommands
5
+
6
+ def info(message)
7
+ puts message
8
+ end
9
+
10
+ module CLI
11
+
12
+ def run
13
+ parse_options
14
+ if @subcommand && self.respond_to?(@subcommand)
15
+ begin
16
+ self.send @subcommand, @args
17
+ rescue Object => e
18
+ error e
19
+ end
20
+ else
21
+ help
22
+ end
23
+ end
24
+
25
+ def error(e)
26
+ puts 'Error: ' + e.to_s
27
+ end
28
+
29
+ def help
30
+ puts print_actions
31
+ end
32
+
33
+ def parse_options
34
+ @options = {}
35
+ global_options do |opts|
36
+ opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
37
+ opts.description = "git-scribe helps you write books with the power of Git"
38
+ opts.separator ""
39
+ opts.separator "Global options are:"
40
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
41
+ @options[:verbose] = v
42
+ end
43
+ end
44
+
45
+ command :init do |opts|
46
+ opts.banner = "Usage: git scribe init (directory)"
47
+ opts.description = "initialize a new book layout"
48
+ opts.on("-l", "--lang", "choose a default language (en)") do |v|
49
+ @options[:lang] = lang || 'en'
50
+ end
51
+ end
52
+
53
+ command :gen do |opts|
54
+ opts.banner = "Usage: git scribe gen [options]"
55
+ opts.description = "generate digital formats"
56
+ end
57
+
58
+ command :check do |opts|
59
+ opts.banner = "Usage: git scribe check"
60
+ opts.description = "checks for system requirements for doc generation"
61
+ end
62
+
63
+ @subcommand = opt_parse
64
+ @args = ARGV
65
+ end
66
+
67
+ # DISPLAY HELPER FUNCTIONS #
68
+
69
+ def l(info, size)
70
+ clean(info)[0, size].ljust(size)
71
+ end
72
+
73
+ def r(info, size)
74
+ clean(info)[0, size].rjust(size)
75
+ end
76
+
77
+ def clean(info)
78
+ info.to_s.gsub("\n", ' ')
79
+ end
80
+
81
+ end
82
+
83
+ include CLI
84
+ end
@@ -0,0 +1,222 @@
1
+ class GitScribe
2
+ module Generate
3
+ # generate the new media
4
+ def gen(args = [])
5
+ type = first_arg(args) || 'all'
6
+ prepare_output_dir
7
+
8
+ gather_and_process
9
+
10
+ types = type == 'all' ? OUTPUT_TYPES : [type]
11
+
12
+ ret = false
13
+ output = []
14
+ Dir.chdir("output") do
15
+ types.each do |out_type|
16
+ call = 'do_' + out_type
17
+ if self.respond_to? call
18
+ ret = self.send call
19
+ else
20
+ die "NOT A THING: #{call}"
21
+ end
22
+ end
23
+ # clean up
24
+ `rm #{BOOK_FILE}`
25
+ ret
26
+ end
27
+ end
28
+
29
+ def prepare_output_dir
30
+ Dir.mkdir('output') rescue nil
31
+ Dir.chdir('output') do
32
+ Dir.mkdir('stylesheets') rescue nil
33
+ from_stdir = File.join(SCRIBE_ROOT, 'stylesheets')
34
+ FileUtils.cp_r from_stdir, '.'
35
+ end
36
+ end
37
+
38
+ def a2x(type)
39
+ "a2x -f #{type} -d book "
40
+ end
41
+
42
+ def a2x_wss(type)
43
+ a2x(type) + " --stylesheet=stylesheets/handbookish.css"
44
+ end
45
+
46
+ def do_pdf
47
+ info "GENERATING PDF"
48
+ # TODO: syntax highlighting (fop?)
49
+ ex("asciidoc -b docbook #{BOOK_FILE}")
50
+ strparams = {'callout.graphics' => 0,
51
+ 'navig.graphics' => 0,
52
+ 'admon.textlabel' => 1,
53
+ 'admon.graphics' => 0}
54
+ param = strparams.map { |k, v| "--stringparam #{k} #{v}" }.join(' ')
55
+ cmd = "xsltproc --nonet #{param} --output #{local('book.fo')} #{base('docbook-xsl/fo.xsl')} #{local('book.xml')}"
56
+ ex(cmd)
57
+ cmd = "fop -fo #{local('book.fo')} -pdf #{local('book.pdf')}"
58
+ ex(cmd)
59
+ #puts `#{a2x('pdf')} -v --fop #{BOOK_FILE}`
60
+ if $?.exitstatus == 0
61
+ 'book.pdf'
62
+ end
63
+ end
64
+
65
+ def do_epub
66
+ info "GENERATING EPUB"
67
+ # TODO: look for custom stylesheets
68
+ cmd = "#{a2x_wss('epub')} -v #{BOOK_FILE}"
69
+ if ex(cmd)
70
+ 'book.epub'
71
+ end
72
+ end
73
+
74
+ def do_html
75
+ info "GENERATING HTML"
76
+ # TODO: look for custom stylesheets
77
+ #puts `#{a2x_wss('xhtml')} -v #{BOOK_FILE}`
78
+ styledir = local('stylesheets')
79
+ cmd = "asciidoc -a stylesdir=#{styledir} -a theme=handbookish #{BOOK_FILE}"
80
+ ex(cmd)
81
+ 'book.html'
82
+ end
83
+
84
+ def do_site
85
+ info "GENERATING SITE"
86
+ # TODO: check if html was already done
87
+ ex("asciidoc -b docbook #{BOOK_FILE}")
88
+ xsldir = base('docbook-xsl/xhtml')
89
+ ex("xsltproc --stringparam html.stylesheet stylesheets/handbookish.css --nonet #{xsldir}/chunk.xsl book.xml")
90
+
91
+ source = File.read('index.html')
92
+ html = Nokogiri::HTML.parse(source, nil, 'utf-8')
93
+
94
+ sections = []
95
+ c = -1
96
+
97
+ # each chapter
98
+ html.css('.toc > dl').each do |section|
99
+ section.children.each do |item|
100
+ if item.name == 'dt' # section
101
+ c += 1
102
+ sections[c] ||= {'number' => c}
103
+ link = item.css('a').first
104
+ sections[c]['title'] = title = link.text
105
+ sections[c]['href'] = href = link['href']
106
+ clean_title = title.downcase.gsub(/[^a-z0-9\-_]+/, '_') + '.html'
107
+ sections[c]['link'] = clean_title
108
+ if href[0, 10] == 'index.html'
109
+ sections[c]['link'] = 'title.html'
110
+ end
111
+ sections[c]['sub'] = []
112
+ end
113
+ if item.name == 'dd' # subsection
114
+ item.css('dt').each do |sub|
115
+ link = sub.css('a').first
116
+ data = {}
117
+ data['title'] = title = link.text
118
+ data['href'] = href = link['href']
119
+ data['link'] = sections[c]['link'] + '#' + href.split('#').last
120
+ sections[c]['sub'] << data
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ book_title = html.css('head > title').text
127
+ content = html.css('body > div')[1]
128
+ content.css('.toc').first.remove
129
+ content = content.inner_html
130
+
131
+ sections.each do |s|
132
+ content.gsub!(s['href'], s['link'])
133
+ end
134
+
135
+ template_dir = File.join(SCRIBE_ROOT, 'site', 'default')
136
+
137
+ # copy the template files in
138
+ files = Dir.glob(template_dir + '/*')
139
+ FileUtils.cp_r files, '.'
140
+
141
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_dir)
142
+ index_template = Liquid::Template.parse(File.read(File.join(template_dir, 'index.html')))
143
+ page_template = Liquid::Template.parse(File.read(File.join(template_dir, 'page.html')))
144
+
145
+ # write the index page
146
+ main_data = {
147
+ 'book_title' => book_title,
148
+ 'sections' => sections
149
+ }
150
+ File.open('index.html', 'w+') do |f|
151
+ f.puts index_template.render( main_data )
152
+ end
153
+
154
+ # write the title page
155
+ File.open('title.html', 'w+') do |f|
156
+ data = {
157
+ 'title' => sections.first['title'],
158
+ 'sub' => sections.first['sub'],
159
+ 'prev' => {'link' => 'index.html', 'title' => "Main"},
160
+ 'home' => {'link' => 'index.html', 'title' => "Home"},
161
+ 'next' => sections[1],
162
+ 'content' => content
163
+ }
164
+ data.merge!(main_data)
165
+ f.puts page_template.render( data )
166
+ end
167
+
168
+ # write the other pages
169
+ sections.each_with_index do |section, i|
170
+
171
+ if i > 0 # skip title page
172
+ source = File.read(section['href'])
173
+ html = Nokogiri::HTML.parse(source, nil, 'utf-8')
174
+
175
+ content = html.css('body > div')[1].to_html
176
+ sections.each do |s|
177
+ content.gsub!(s['href'], s['link'])
178
+ end
179
+
180
+ File.open(section['link'], 'w+') do |f|
181
+ next_section = nil
182
+ if i <= sections.size
183
+ next_section = sections[i+1]
184
+ end
185
+ data = {
186
+ 'title' => section['title'],
187
+ 'sub' => section['sub'],
188
+ 'prev' => sections[i-1],
189
+ 'home' => {'link' => 'index.html', 'title' => "Home"},
190
+ 'next' => next_section,
191
+ 'content' => content
192
+ }
193
+ data.merge!(main_data)
194
+ f.puts page_template.render( data )
195
+ end
196
+ #File.unlink(section['href'])
197
+
198
+ info i
199
+ info section['title']
200
+ info section['href']
201
+ info section['link']
202
+ end
203
+
204
+ #File.unlink
205
+ end
206
+ sections
207
+ end
208
+
209
+ # create a new file by concatenating all the ones we find
210
+ def gather_and_process
211
+ files = Dir.glob("book/*")
212
+ FileUtils.cp_r files, 'output'
213
+ end
214
+
215
+ def ex(command)
216
+ out = `#{command} 2>&1`
217
+ info out
218
+ $?.exitstatus == 0
219
+ end
220
+
221
+ end
222
+ end
@@ -0,0 +1,16 @@
1
+ class GitScribe
2
+ module Init
3
+ # start a new scribe directory with skeleton structure
4
+ def init(args = [])
5
+ name = first_arg(args)
6
+ die("needs a directory name") if !name
7
+ die("directory already exists") if File.exists?(name)
8
+
9
+ info "inititalizing #{name}"
10
+ from_stdir = File.join(SCRIBE_ROOT, 'template')
11
+ ign = Dir.glob(from_stdir + '/.[a-z]*')
12
+ FileUtils.cp_r from_stdir, name
13
+ FileUtils.cp_r ign, name
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ class GitScribe
2
+ VERSION = '0.0.5'
3
+ end
@@ -0,0 +1 @@
1
+ output
@@ -0,0 +1,5 @@
1
+ ---
2
+ publish: true
3
+ edition: 0.1
4
+ language: en
5
+ version: 1.0
@@ -0,0 +1,12 @@
1
+ require File.expand_path "../test_helper", __FILE__
2
+
3
+ context "scribe check tests" do
4
+ setup do
5
+ @scribe = GitScribe.new
6
+ end
7
+
8
+ test "scribe can check for programs it needs" do
9
+ status = @scribe.check
10
+ assert_equal status.size, 5
11
+ end
12
+ end
data/test/gen_test.rb ADDED
@@ -0,0 +1,78 @@
1
+ require File.expand_path "../test_helper", __FILE__
2
+
3
+ context "scribe gen tests" do
4
+ setup do
5
+ @scribe = GitScribe.new
6
+ end
7
+
8
+ test "will not respond to non-thing" do
9
+ assert_raise RuntimeError do
10
+ @scribe.gen('mofo')
11
+ end
12
+ end
13
+
14
+ test "scribe can generate single page html" do
15
+ in_temp_dir do
16
+ @scribe.init('t')
17
+ Dir.chdir('t') do
18
+ file = @scribe.gen('html')
19
+ assert_equal 'book.html', file
20
+ out = Dir.glob('output/**/*')
21
+ assert out.include? 'output/book.html'
22
+ assert out.include? 'output/image'
23
+ assert out.include? 'output/stylesheets/handbookish.css'
24
+ end
25
+ end
26
+ end
27
+
28
+ test "scribe can generate site html" do
29
+ in_temp_dir do
30
+ @scribe.init('t')
31
+ Dir.chdir('t') do
32
+ data = @scribe.gen('site')
33
+ out = Dir.glob('output/**/*')
34
+ assert out.include? 'output/index.html'
35
+ assert out.include? 'output/the_first_chapter.html'
36
+ assert out.include? 'output/the_second_chapter.html'
37
+ assert out.include? 'output/image'
38
+ assert out.include? 'output/stylesheets/handbookish.css'
39
+ end
40
+ end
41
+ end
42
+
43
+ test "scribe can generate a pdf" do
44
+ in_temp_dir do
45
+ @scribe.init('t')
46
+ Dir.chdir('t') do
47
+ data = @scribe.gen('pdf')
48
+ assert_equal data, 'book.pdf'
49
+ out = Dir.glob('output/**/*')
50
+ assert out.include? 'output/book.pdf'
51
+ end
52
+ end
53
+ end
54
+
55
+ test "scribe can generate a epub" do
56
+ in_temp_dir do
57
+ @scribe.init('t')
58
+ Dir.chdir('t') do
59
+ data = @scribe.gen('epub')
60
+ assert_equal data, 'book.epub'
61
+ out = Dir.glob('output/**/*')
62
+ assert out.include? 'output/book.epub'
63
+ end
64
+ end
65
+ end
66
+
67
+ xtest "scribe can generate docbook" do
68
+ end
69
+
70
+ xtest "scribe can generate a mobi" do
71
+ end
72
+
73
+ xtest "scribe can generate all" do
74
+ end
75
+
76
+ xtest "scribe doesn't regen already generated assets" do
77
+ end
78
+ end