mandown 0.0.7 → 0.0.8

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/Manifest.txt CHANGED
@@ -4,8 +4,10 @@ Manifest.txt
4
4
  README.txt
5
5
  Rakefile
6
6
  bin/bibdown
7
+ bin/mandown-sample
7
8
  config/hoe.rb
8
9
  config/requirements.rb
10
+ lib/bibdown_lib.rb
9
11
  lib/mandown.rb
10
12
  lib/mandown/version.rb
11
13
  log/debug.log
@@ -18,6 +20,7 @@ tasks/environment.rake
18
20
  tasks/website.rake
19
21
  test/test_helper.rb
20
22
  test/test_mandown.rb
23
+ test/test_bibdown.rb
21
24
  website/index.html
22
25
  website/index.txt
23
26
  website/javascripts/rounded_corners_lite.inc.js
data/README.txt CHANGED
@@ -1,89 +1,11 @@
1
1
  = Mandown Readme
2
2
 
3
- == Introduction
3
+ Mandown provides simple extensions to the "Markdown":http://daringfireball.net/projects/markdown/ syntax that are useful for academic writing.
4
4
 
5
- Mandown is a set of tools that allow you to produce academic manuscripts using
6
- Markdown syntax (see http://daringfireball.net/projects/markdown/). It
7
- provides simple extensions to the Markdown syntax that are useful for academic
8
- writing.
5
+ For up-to-date information about Mandown, please see the "Mandown website":http://mandown.rubyforge.org/
9
6
 
10
- Using a combination of Mandown (and its syntax), the Markdown syntax and a
11
- Markdown processor (such as Pandoc, see http://johnmacfarlane.net/pandoc/) it is
12
- possible to write academic manuscripts using a simple plain-text syntax which
13
- can then be converted into useful formats such as Rich Text Format (RTF, which
14
- can in turn be opened by Microsoft Word), PDF, LaTeX etc.
15
7
 
16
- The advantage of using Mandown over a Word-processor or a document preparation
17
- system such as LaTeX is that is allows manuscripts to be kept in a plain text
18
- format (ASCII/UTF-8/etc.) while allowing you to convert to Word or LaTeX. This
19
- is particularly useful if you don't want to draft in Word but have a co-author
20
- who has a confusing attachment to Microsoft products. Let them hack at the Word
21
- version you prepared for them, then bring their changes into your Mandown source
22
- file (this task may still be tricky, sorry...). Your papers will be readable
23
- 'forever' and you won't need to worry about losing your data.
24
-
25
- Mandown is not attempting to be a document preparation system like LaTeX; if you
26
- can use LaTeX you probably should---it's far more powerful than Mandown.
27
- However, it can be difficult to convert from LaTeX to Word format, and this is
28
- when Mandown may become useful to you.
29
-
30
- The Mandown tools are designed to be used in a UNIX pipeline (see the Usage
31
- section, below). You may choose to use one or more of the tools. You may also
32
- want to develop your own tools which I would be glad to consider adding to
33
- Mandown.
34
-
35
- The name Mandown is a portmanteaux of 'manuscript' and 'Markdown', which I find
36
- slightly amusing ("Man down!").
37
-
38
-
39
- == Usage:
40
-
41
- The Mandown tools are designed to be chained together on the UNIX command line
42
- in a pipeline. Here is an example of how to process a file containing a bibliography with bibdown and convert the resulting file into an RTF file using Pandoc (the resulting RTF file could then be opened using Word, for example; ignore the initial > characters, which denote the start of a new command):
43
-
44
- > cat sample-manuscript.txt | bibdown > sample-out.txt
45
- > pandoc --smart -s sample-out.txt -o sample.rtf
46
-
47
- This assumes that the Mandown tool directory and the Pandoc program are on your system's $PATH.
48
-
49
- If you are unfamiliar with the UNIX command line, here's what's going on:
50
-
51
- 1. The cat program reads the sample-manuscript.txt and sends it to the standard output device (usually the terminal).
52
- 2. The contents of sample-manuscript.txt are intercepted by a 'pipe' (denoted by the '|' character) which sends them to the bibdown program.
53
- 3. The bibdown program processes the bibliography and sends the resulting manuscript to the standard output device.
54
- 4. The processed manuscript is intercepted by the '>' operator, which causes standard output to be the file called sample-out.txt. We now have a manuscript with proper citations and a bibliography in Markdown format.
55
- 5. We then run Pandoc on the result to create an RTF file.
56
-
57
- The Mandown tools are designed to be chained together into a pipeline, so for example you might do:
58
-
59
- > cat my-manu.txt | bibdown | eqndown | secdown > my-manu-out.txt
60
- > pandoc ...
61
-
62
- Note: only bibdown is currently implemented.
63
-
64
-
65
- == FAQ, gotchas and common problems:
66
-
67
- Q1: How do I ...
68
- A1: Email me; there isn't much implemented yet, but the bare bones are there. No guarantees, but I'll try and take your feature requests into consideration. Or better yet, send me code!
69
-
70
- Q2: I have a problem running bibdown.
71
- A2: Check that you are not using hard tabs; Ruby's YAML parser requires that soft tabs (i.e. emulated using spaces). Also check the alignment of the various fields.
72
-
73
- Q3: bibdown chokes on titles etc. that contain colons.
74
- A3: Surround the title in quotes; these will be ignored, but fix the problem. I think this is a bug in Ruby's YAML parser (as of Ruby 1.8.6).
75
-
76
- Q4: The tools don't run.
77
- A4: Mandown requires Ruby version 1.8.6 or higher. Check that the tools are executable (try 'chmod u+x bibdown', for example). Check that the Mandown directory is on your system's $PATH. Try running the using the Ruby interpreter explicitly (e.g. 'ruby bibdown' rather than just 'bibdown').
78
-
79
-
80
- == Author and Contact Information:
81
-
82
- The Mandown set of tools was written by Chris Rose. You can contact me at
83
- mandown@microserf.org.uk.
84
-
85
-
86
- == Copyright and license:
8
+ = Copyright and license:
87
9
 
88
10
  Copyright (c) 2008 Chris Rose
89
11
 
data/bin/bibdown CHANGED
@@ -17,525 +17,7 @@
17
17
  #
18
18
  ################################################################################
19
19
 
20
- require 'yaml'
21
-
22
-
23
- # Define the text that is displayed when the user asks for documentation
24
- def documentation
25
- <<END
26
-
27
-
28
- bibdown --- part of the Mandown set of tools.
29
-
30
- bibdown processes standard input, builds a bibliography from a YAML-format set
31
- of references and inserts citation keys.
32
-
33
- Copyright © 2008 Chris Rose.
34
- Distributed according to the GNU General Public License.
35
-
36
- Usage:
37
- ------
38
- cat infile.txt | bibdown > outfile.txt
39
-
40
- Syntax:
41
- -------
42
-
43
- Place references at the end of your Markdown file in a level 1 section
44
- called 'Bibliography' using the exact string '# Bibliography' (as given in the
45
- example below). Cite references in your text using 'cite:MyKey', where 'MyKey'
46
- is a key to one of your references. Keys may contain any characters, but end
47
- with a space character (i.e. 'cite:SomeKey' refers to the key 'SomeKey', while
48
- 'cite:Some Key' refers to the key 'Some').
49
-
50
- ------------------------------- Example -------------------------------------
51
- ...
52
- This is some text that needs to cite the very important work of Jones and
53
- Smith cite:Jones.
54
- ...
55
-
56
- # Bibliogrqaphy
57
-
58
- Jones:
59
- authors: Jones, Bob & Smith, Fred J.
60
- title: Spaghetti-Wall Interactions
61
- journal: Am. J. Pasta Phys.
62
- volume: 3
63
- number: 2
64
- month: January
65
- year: 2008
66
- pages: 111--112
67
- note: In press.
68
- ------------------------------- End of example ------------------------------
69
-
70
- Suppoted fields:
71
- ----------------
72
-
73
- The following fields are supported by bibdown and all are optional; you may
74
- use other arbitrarily-named fields, but they will be ignored (by this version
75
- of bibdown, at least).
76
-
77
- authors -- Use 'surname, first names' format; separate authors with '&'.
78
- e.g. "Einstein, Albert & Bohr, Neils"
79
- organization -- Use if the publication is authored by an organization.
80
- e.g. "Amnesty International"
81
- title -- The title of the reference.
82
- e.g. "Some Clever Stuff on Quantum Physics"
83
- journal -- The name of the journal; this field causes the reference to be
84
- treated as an article in a journal.
85
- e.g. "Int. J. Quan. Phys."
86
- conference -- The name of the conference; this field causes the reference to
87
- be treated as a paper in a conference proceedings.
88
- e.g. "Medical Image Understanding and Analysis"
89
- booktitle -- The title of a book; this field causes the reference to be
90
- treated as a book.
91
- e.g. "Moby Dick"
92
- chapter -- The chapter in a book being cited; only valid for references
93
- that use the booktitle field.
94
- e.g. "4"
95
- edition -- The edition of a book being cited; only valid for references
96
- that use the booktitle field.
97
- e.g. "5"
98
- editors -- The editors of a book being cited; only valid for references
99
- that use the booktitle field.
100
- e.g. "Harris, Thomas & Hopper, Dennis"
101
- isbn -- The ISBN number of a book being cited; only valid for references
102
- that use the booktitle field.
103
- e.g. "9783540356257"
104
- month -- The month of publication.
105
- e.g. "January"
106
- volume -- The volume of the publication being cited.
107
- e.g. "2"
108
- number -- The number/issue of the journal article being cited; only valid for
109
- references that use the journal field.
110
- e.g. "2"
111
- pages -- The pages in the publication being referred to.
112
- e.g. "201--211"
113
- series -- The series the book being cited belongs to; only valid for
114
- references that use the booktitle field.
115
- e.g. "Mathematical Statistics"
116
- url -- A URL for the publication being cited.
117
- e.g. "http://www.something.com/somedocument"
118
- accessed -- The date the URL was accessed (note: do not use this field without
119
- also including a URL).
120
- e.g. "28 January 2008"
121
- year -- The year the publication being cited was published.
122
- e.g. 2008
123
- note -- Any notable comment about the publication being cited.
124
- e.g. "In press."
125
-
126
-
127
- Notes:
128
- ------
129
-
130
- You must use soft tabs (emulated using spaces) in the bibliography. If you
131
- need to include a colon in the reference (e.g. in the title field), you
132
- will need to surround the field entry in quotes (e.g. "title: 'Gnocci: nasty
133
- or nice?'").
134
-
135
- If you are going to process the resulting file (outfile.txt, in the usage
136
- example given above), you may wish to use a double-dash for page ranges
137
- (and be sure to use the 'smart typography' mode of Pandoc)---see the example
138
- above.
139
-
140
- See also:
141
- ---------
142
-
143
- Markdown -- http://daringfireball.net/projects/markdown/
144
- Pandoc -- http://johnmacfarlane.net/pandoc/
145
-
146
- END
147
- end
148
-
149
-
150
- # Given a symbol identifying a part of a citation (e.g. :journal), return the
151
- # separator string that should follow it (e.g. a '. ' follows the name of the
152
- # journal). (Note: include any following space!)
153
- def get_sep(part)
154
- sep = case part
155
- when :authors, :organization, :title, :booktitle, :isbn, :series, :accessed, :year
156
- '. '
157
- when :journal, :conference, :chapter, :edition, :pages, :url
158
- ', '
159
- when :editors
160
- ', editors. '
161
- when :month, :note
162
- ' '
163
- when :number, :volume
164
- ''
165
- end
166
-
167
- sep
168
- end
169
-
170
- # Define a function that takes a string and returns that string marked as being of :normal (upright) or :italic using Markdown notation.
171
- def markdown_format(string, style)
172
- case style
173
- when :normal: string
174
- when :italic: '*' + string + '*'
175
- end
176
- end
177
-
178
- # Define a function to render a string as normal using Markdown notation.
179
- def r_norm(string)
180
- markdown_format(string, :normal)
181
- end
182
-
183
- # Define a function to render a string as italic using Markdown notation.
184
- def r_ital(string)
185
- markdown_format(string, :italic)
186
- end
187
-
188
-
189
- # Given a bib entry (a hash that maps the parts of a reference to the content
190
- # for that reference), construct a string that can be used in a paper as the
191
- # bibliographic entry for that entry. Also return information that can be used
192
- # to sort the bibliography (first author surname, publication year). Also
193
- # return the key that was used in the text to refer to this citation. Return a
194
- # hash with fields :reference (containing the reference), :sort_info and :key.
195
- # :sort_info is a hash with fields :surname and :year.
196
- #
197
- # See the documentation string above for details on what fields are supported
198
- # and how they should behave.
199
- def make_bib_entry_string(bib_entry, key)
200
- # We'll encode the order in which the parts of the reference appear for the
201
- # three types of reference in three arrays; we'll associate these arrays
202
- # with symbols that specify the reference type.
203
- order = {
204
- :journal =>
205
- [:authors, :organization, :title, :journal, :volume, :number, :pages,
206
- :month, :year, :url, :accessed, :note],
207
- :conference =>
208
- [:authors, :organization, :title, :conference, :editors, :volume, :pages,
209
- :month, :year, :isbn, :url, :accessed, :note],
210
- :book =>
211
- [:authors, :organization, :editors, :booktitle, :series, :edition,
212
- :volume, :chapter, :pages, :month, :year, :isbn, :url, :accessed,
213
- :note]}
214
-
215
- # Cope with the misc type.
216
- order[:misc] = order[:journal]
217
-
218
- # Use an associative array to specify how each part of a citation should be
219
- # styled. We map from the parts to functions which perform the required
220
- # styling.
221
- styles = {:authors => proc {|x| r_norm(x)},
222
- :organization => proc {|x| r_norm(x)}, :title => proc {|x| r_norm(x)},
223
- :journal => proc {|x| r_ital(x)}, :conference => proc {|x| r_ital(x)},
224
- :booktitle => proc {|x| r_ital(x)}, :chapter => proc {|x| r_norm(x)},
225
- :edition => proc {|x| r_norm(x)}, :editors => proc {|x| r_norm(x)},
226
- :isbn => proc {|x| r_norm(x)}, :month => proc {|x| r_norm(x)},
227
- :note => proc {|x| r_norm(x)}, :number => proc {|x| r_norm(x)},
228
- :pages => proc {|x| r_norm(x)}, :series => proc {|x| r_norm(x)},
229
- :url => proc {|x| r_norm(x)}, :accessed => proc {|x| r_norm(x)},
230
- :volume => proc {|x| r_norm(x)}, :year => proc {|x| r_norm(x)}}
231
-
232
- # Make a copy for later, as we alter the original bib_entry object.
233
- org_bib_entry = bib_entry.clone
234
-
235
- # Make the author string and replace the entry in the bib_entry with the
236
- # formatted version. Do similarly with the editors.
237
- bib_entry['authors'] =
238
- make_author_string(bib_entry['authors']) if !bib_entry['authors'].nil?
239
- bib_entry['editors'] =
240
- make_author_string(bib_entry['editors']) if !bib_entry['editors'].nil?
241
-
242
- # See if we're making a journal article, conference paper or book reference.
243
- ref_type = :journal unless bib_entry['journal'].nil?
244
- ref_type = :conference unless bib_entry['conference'].nil?
245
- ref_type = :book unless bib_entry['booktitle'].nil?
246
- if !(defined? ref_type) || ref_type.nil?
247
- ref_type = :misc
248
- STDERR.puts('Note: Reference type not found for reference ' + key)
249
- end
250
-
251
- # Get the order for the type of entry we're dealing with.
252
- order = order[ref_type]
253
-
254
- # Iterate over the parts of the citation for this type of reference and
255
- # build the bibliography entry.
256
- bib_entry_string = ''
257
- order.each do |part_name|
258
- # Construct the part of the entry for the given part_name, taking into
259
- # account the fact that some parts need to be formatted in certain ways.
260
- if bib_entry[part_name.to_s] # If there is an entry for this part name...
261
- part = bib_entry[part_name.to_s].to_s
262
- else
263
- part = ''
264
- end
265
-
266
- # Format the part of the reference using the appropriate style.
267
- part = styles[part_name].call(part)
268
-
269
- part = case part_name
270
- when :authors, :organization, :booktitle, :isbn, :series, :year
271
- part + '. '
272
- when :title
273
- # Only add an '.' if doesn't already end with a punctuation character.
274
- if /[[:punct:]]$/.match(part): part + ' '
275
- else part + '. '
276
- end
277
- when :conference
278
- 'In proc. ' + part + ', '
279
- when :journal, :conference, :chapter, :edition
280
- part + ', '
281
- when :editors
282
- part + ', editors. '
283
- when :month
284
- part + ' '
285
- when :volume
286
- part
287
- when :number, :note
288
- '(' + part + ')'
289
- when :pages
290
- if ref_type == :journal
291
- ':' + part + ', '
292
- elsif ref_type == :conference || ref_type == :book
293
- 'pp' + part + ', '
294
- end
295
- when :url
296
- 'Available at: ' + part
297
- when :accessed
298
- ', accessed ' + part + '. '
299
- else
300
- part
301
- end
302
-
303
- bib_entry_string += part if bib_entry[part_name.to_s]
304
- end
305
-
306
- # Make sure the bib_entry_string ends with a punctuation character,
307
- # appending a full stop if it doesn't.
308
- bib_entry_string.strip!
309
- bib_entry_string += '.' unless /[[:punct:]]$/.match(bib_entry_string)
310
-
311
- # Get the surname for sorting purposes. Use the author as first preference
312
- # if it is available, otherwise use the organisation, otherwise use a sort
313
- # surname that will place it last.
314
- sort_surname = 'ZZZ' # The default if we can't find something better.
315
- sort_surname =
316
- org_bib_entry[:organization] if !bib_entry['organization'].nil?
317
- sort_surname =
318
- get_first_author_surname(org_bib_entry) if !bib_entry['author'].nil?
319
-
320
-
321
- # Make the hash to return.
322
- { :reference => bib_entry_string,
323
- :key => key,
324
- :sort_info => {:surname => sort_surname, :year => bib_entry['year']}}
325
- end
326
-
327
- # Return the surname of the first author in lowercase.
328
- def get_first_author_surname(bib_entry)
329
- make_author_string(
330
- bib_entry['authors'], true, true).split[0][0..-2].downcase
331
- end
332
-
333
-
334
- # Given a string of the form 'Chris James' turn it into a string of the form 'C. J.'
335
- def make_initials(firstnames)
336
- firstnames = firstnames.split(' ')
337
- firstnames.each_index do |i|
338
- firstnames[i] = firstnames[i][0].chr + '.'
339
- end
340
- end
341
-
342
- # Given a string of the form 'Rose, Chris & Jones, Bob', make an authors
343
- # string that can be placed in the bibliography.
344
- #
345
- # use_initials specifies whether the full firstnames are used, or whether
346
- # initials are used instead.
347
- #
348
- # surname_first specifies whether the author surnames should appear before
349
- # their first names or initials.
350
- def make_author_string(authors, use_initials=true, surname_first=false)
351
- # Strip out the individual authors and remove leading and trailing
352
- # whitespace, and split each into surname and firstnames.
353
- authors = authors.split('&')
354
- authors.each_index do |i|
355
- authors[i].strip!
356
- authors[i] = authors[i].split(',')
357
- authors[i][0].strip!
358
- authors[i][1].strip!
359
- end
360
-
361
- # If we have to use first initials for the first names, then make them.
362
- if use_initials
363
- authors.each_index do |i|
364
- authors[i][1] = make_initials(authors[i][1])
365
- end
366
- end
367
-
368
- # Now make the authors string.
369
- authors_string = ''
370
- authors.each_index do |i|
371
- # Get a string for the forename(s) for the i-th author.
372
- this_forenames = ''
373
- authors[i][1].each do |name_or_initial|
374
- this_forenames += name_or_initial + ' '
375
- end
376
-
377
- # Concatenate the forename(s) and surname in the appropriate order.
378
- if surname_first
379
- authors_string += authors[i][0] + ', '
380
- authors_string += this_forenames
381
- else
382
- authors_string += this_forenames
383
- authors_string += authors[i][0]
384
- end
385
- authors_string += ', ' unless i == authors.length-1 or i == authors.length-2
386
- authors_string += ' and ' if i == authors.length-2
387
- end
388
-
389
- authors_string.strip! # Remove leading and trailing whitespace.
390
- authors_string # Return the authors string.
391
- end
392
-
393
-
394
- # Given an array of bib_entries, each made using the make_bib_entry_string
395
- # function, sort this array according to first author surname, or year of
396
- # publication, or by the order in which the papers were cited in the text.
397
- #
398
- # keys_in_order must be an array containing the keys used in the text, in the
399
- # order the keys appear in the text, without repetition. by must be one of
400
- # :surname, :year or :order_in_text
401
- def sort_bib_entries(bib_entries, keys_in_order, by = :surname)
402
- case by
403
- when :surname, :year
404
- bib_entries.sort {|x,y| x[:sort_info][by] <=> y[:sort_info][by]}
405
- when :order_in_text
406
- to_return = []
407
- keys_in_order.each do |key|
408
- bib_entries.each do |entry|
409
- to_return.push(entry) if entry[:key] == key
410
- end
411
- end
412
- to_return
413
- end
414
- end
415
-
416
-
417
- # Given a string containing the YAML for the bibliography, and an array
418
- # containing the keys in the order they appear in the text (without
419
- # repetitions), make an array of strings where each string is a bibliographic
420
- # entry (i.e. can be placed directly in the bibliography). The entries
421
- # returned will be sorted in an appropriate order.
422
- def make_bib_entries(bibliography_yaml, keys_in_order)
423
- # Convert the YAML text to a Ruby data type.
424
- objs = YAML.load(bibliography_yaml)
425
-
426
- # Make each bibliography entry string (the references).
427
- bib_entries = Array.new
428
- objs.each_key do |key|
429
- bib_entries.push(make_bib_entry_string(objs[key], key))
430
- end
431
-
432
- # Sort the references & return.
433
- sort_bib_entries(bib_entries, keys_in_order, :order_in_text)
434
- end
435
-
436
- # Define a function that returns true if bib_entries contains an entry for a
437
- # given citation key.
438
- def has_key?(key, bib_entries)
439
- ret_val = false
440
- bib_entries.each do |entry|
441
- ret_val = true if entry[:key] == key
442
- end
443
- ret_val
444
- end
445
-
446
- # Get an array that contains the reference keys in the order they are cited,
447
- # without repetitions.
448
- def get_keys_in_order(plaintext)
449
- all_keys = plaintext.scan(/cite:\w*/)
450
- all_keys.uniq! # Remove duplicates.
451
- uniq_keys = []
452
- all_keys.each {|x| uniq_keys.push(x.split('cite:')[1])} # Remove the 'cite:'
453
- uniq_keys
454
- end
455
-
456
- # Convert bib_entries into a string that can be placed at the end of the
457
- # plaintext as the bibliography. The parenthesis style using the
458
- # citation_parens argument.
459
- def render_bibliography(bib_entries, citation_parens)
460
- ret_val = "\n"
461
- bib_entries.each_index do |i|
462
- ret_val += # The reference number.
463
- citation_parens[0].chr + (i+1).to_s + citation_parens[1].chr
464
- ret_val += ' ' + bib_entries[i][:reference] # The reference.
465
- ret_val += " \n" # __\n is Markdown for a linebreak.
466
- end
467
-
468
- ret_val
469
- end
470
-
471
- # Given the plaintext containing the key-based citations, and the bib_entries,
472
- # make the final manuscript by replacing the key-based citations (in the text)
473
- # with human-readable citations and place the bibliography at the end. Specify
474
- # the parenthesis style using the optional citation_parens argument.
475
- def make_manuscript(plaintext, bib_entries, citation_parens='[]')
476
- bib_entries.each_index do |i|
477
- plaintext.gsub!("cite:#{bib_entries[i][:key]}",
478
- citation_parens[0].chr + "#{i+1}" + citation_parens[1].chr)
479
- end
480
-
481
- plaintext + render_bibliography(bib_entries, citation_parens)
482
- end
483
-
484
- # Check the final manuscript for instances of cite:SomeKey (for example), and
485
- # return an array of messages identifying the keys that were not defined in
486
- # the bibliography.
487
- def check_missing_citations(manuscript)
488
- ret_val = []
489
- # Get the remaining keys.
490
- remaining_keys = get_keys_in_order(manuscript)
491
- remaining_keys.each do |key|
492
- ret_val.push('The following reference key was undefined: ' + key)
493
- end
494
-
495
- ret_val
496
- end
497
-
498
- # Read the text containing the citations from standard input, process the
499
- # references and send the result to standard output, reporting errors to
500
- # standard error. This program is written to allow it to be chained with other
501
- # manuscript-processing tools in a UNIX pipeline. To read/write from/to files,
502
- # do:
503
- #
504
- # cat my-paper.txt | ruby make_paper.rb > my-paper-with-bib.txt
505
- def main
506
- # Handle request for documentation.
507
- if ARGV.length > 0 && ARGV[0] == '--help'
508
- puts documentation
509
- exit
510
- end
511
-
512
- # Read the .txt file from standard input and get the plain text and the
513
- # bibliography
514
- parts = STDIN.readlines('# Bibliography')
515
- plaintext = parts[0]
516
- bibliography_yaml = parts[1]
517
-
518
- # Get an array that contains the reference keys in the order they are cited,
519
- # without repetitions.
520
- keys_in_order = get_keys_in_order(plaintext)
521
-
522
- # Make a list of bibliography enties, sorted in the correct order.
523
- bib_entries = make_bib_entries(bibliography_yaml, keys_in_order)
524
-
525
- # Now make the final manuscript by replacing the key-based citations (in the
526
- # text) with human-readable citations and place the bibliography at the end.
527
- manuscript = make_manuscript(plaintext, bib_entries)
528
-
529
- # Send the manuscript to standard output.
530
- STDOUT.puts(manuscript)
531
-
532
- # Now perform some checks for possible user errors and report then on
533
- # standard error.
534
- user_errors = []
535
- user_errors.concat(check_missing_citations(manuscript))
536
- user_errors.each {|x| STDERR.puts(x)} # Report the user errors.
537
-
538
- end
20
+ require 'bibdown_lib'
539
21
 
540
22
  # Entry point
541
- main
23
+ bibdown_main