marker 0.1.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/README ADDED
@@ -0,0 +1,98 @@
1
+ == Marker
2
+
3
+ Marker is a markup language parser designed for two needs:
4
+ # Need to mimic MediaWiki syntax
5
+ # Need to provide multiple output formats
6
+
7
+ Mimicing MediaWiki syntax is not exact. One reason is that the MediaWiki
8
+ parser itself is very complicated and handles many cases specially. It would
9
+ be very difficult to exactly copy the MediaWiki parser and it probably wouldn't
10
+ be worth the time because MediaWiki is intended for a wiki and needs to be
11
+ adapted to be used as a markup lanaguage--especially for multiple output
12
+ formats. The purpose of mimicing MediaWiki syntax is so that users don't have
13
+ to learn more than one markup language, so the implementation doesn't *need* to
14
+ be exact anyway.
15
+
16
+ Marker differs from MediaWiki in several ways, because it is a grammar-based
17
+ implementation. The grammar is written as a
18
+ Treetop[http://treetop.rubyforge.org/] parsing expression grammar (PEG).
19
+
20
+ Not implemented:
21
+ # Table of contents
22
+ # Tables
23
+
24
+ == Use
25
+
26
+ Parsing is done with either Marker.parse or Marker.parse_file. Both parse
27
+ methods will return a parse tree that has to_html and to_s methods that
28
+ "render" the markup. Both render methods will accept an options hash.
29
+
30
+ Example:
31
+ >> require 'marker'
32
+ => true
33
+ >> m = Marker.parse "== heading ==\nparagraph with '''bold''' text"
34
+ => Markup+...
35
+ >> puts m.to_s
36
+ heading
37
+ --------------------------------------------------------------------------------
38
+ paragraph with *bold* text
39
+ => nil
40
+ >> puts m.to_html
41
+ <h2>heading</h2>
42
+ <p>paragraph with <b>bold</b> text</p>
43
+ => nil
44
+
45
+ === Templates
46
+
47
+ Templates are implemented as method calls to a templates module. Each method
48
+ in the templates module is considered a template and can be called using the
49
+ "{{ name }}" syntax. Each template method is expected to take three arguments:
50
+ the render format (:html or :text), an array of positional parameters, and a
51
+ hash of named parameters. For example,
52
+ module MyTemplates
53
+ def logo( format, pos_params, name_params )
54
+ case format
55
+ when :html
56
+ '<img src="/images/logo.png" />'
57
+ else
58
+ ''
59
+ end
60
+ end
61
+ end
62
+
63
+ Template modules are passed to Marker by setting the +templates+ property:
64
+ require 'my_templates'
65
+ require 'marker'
66
+
67
+ Marker.templates = Templates
68
+
69
+ If no template method is found, the template call is printed for debugging:
70
+ >> puts Marker.parse( '{{t|one|two|name=val}}' ).to_s
71
+ render:t( :text, ["one", "two"], {"name"=>"val"} )
72
+
73
+ === Internal Links
74
+
75
+ Internal links are implemented as links with default prefixes. The link prefix
76
+ is specified by setting the +link_base+ property:
77
+ require 'marker'
78
+
79
+ Marker.link_base = 'http://example.com/pages/'
80
+
81
+ >> puts Marker.parse( '[[target|name]]' ).to_html
82
+ <p><a href='http://example.com/pages/target'>name</a></p>
83
+
84
+ The link target is appended to the link prefix, along with a beginning '/'. If
85
+ no link base is given, links are just the link target with a beginning '/'.
86
+ The link base can also be given as a render option.
87
+
88
+ === Unlabelled Links
89
+
90
+ (write me)
91
+
92
+ == Command Line Program
93
+
94
+ == License
95
+
96
+ Marker is copyright 2009 Ryan Blue and distributed under the terms of the GNU
97
+ General Public License (GPL). See the LICENSE file for further information on
98
+ the GPL, or visit http://creativecommons.org/licenses/GPL/2.0/.
data/bin/marker ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ostruct'
5
+ require 'rubygems'
6
+
7
+ begin
8
+ require 'marker'
9
+ rescue LoadError
10
+ $: << File.join( File.dirname(__FILE__), '..', 'lib' )
11
+ require 'marker'
12
+ end
13
+
14
+ options = OpenStruct.new
15
+ options.format = :text
16
+ OptionParser.new do |opts|
17
+ opts.on( '--format FORMAT', [:text, :html],
18
+ 'Specify the output format (text, html)' ) do |format|
19
+ options.format = format
20
+ end
21
+ opts.on_tail('-h', '--help', 'Show this message') do
22
+ puts opts
23
+ exit
24
+ end
25
+ end.parse!
26
+
27
+ files = {}
28
+
29
+ if ARGV.empty? or ARGV.include? '-'
30
+ s = ''
31
+ # the parser expects a full block of text, grab it all
32
+ $stdin.each_line { |l| s << l }
33
+ files[:stdin] = Marker.parse( s )
34
+ end
35
+
36
+ ARGV.each do |f|
37
+ next if f == '-'
38
+ files[f] = Marker.parse_file( f )
39
+ end
40
+
41
+ if files.size > 1
42
+ files.each do |f, t|
43
+ puts "\n==> #{f} <=="
44
+ case options.format
45
+ when :html
46
+ puts t.to_html
47
+ else
48
+ puts t
49
+ end
50
+ end
51
+ else
52
+ # only one, so leave out the file name
53
+ case options.format
54
+ when :html
55
+ puts files.values.first.to_html
56
+ else
57
+ puts files.values.first
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ #--
2
+ # Copyright 2009 Ryan Blue.
3
+ # Distributed under the terms of the GNU General Public License (GPL).
4
+ # See the LICENSE file for further information on the GPL.
5
+ #++
6
+
7
+ require 'treetop'
8
+
9
+ module Treetop #:nodoc:
10
+ module Runtime #:nodoc:
11
+ class SyntaxNode #:nodoc:
12
+ # returns whether the ParseNode matched any text
13
+ def present?
14
+ text_value.any?
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module Marker #:nodoc:
21
+ # used to add methods to all parse nodes.
22
+ class ParseNode < Treetop::Runtime::SyntaxNode
23
+ end
24
+
25
+ # implements collection methods on a list using a recursive grammar definition
26
+ # requires defining +h+ and +r+
27
+ class RecursiveList < ParseNode
28
+ def to_a
29
+ if r
30
+ [h] + r.to_a
31
+ else
32
+ [h]
33
+ end
34
+ end
35
+
36
+ def r
37
+ nil
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,79 @@
1
+ #--
2
+ # Copyright 2009 Ryan Blue.
3
+ # Distributed under the terms of the GNU General Public License (GPL).
4
+ # See the LICENSE file for further information on the GPL.
5
+ #++
6
+
7
+ require 'marker/common'
8
+
9
+ module Marker #:nodoc:
10
+ class Heading < ParseNode
11
+ # HTML-rendered headings, using <h#> tags.
12
+ def to_html( options = {} )
13
+ # find out how deep it is
14
+ d = [s.text_value.size, e.text_value.size].min
15
+ sn = s.text_value.size - d
16
+ en = e.text_value.size - d
17
+ if sn > 0
18
+ "<h#{d}>#{'=' * sn} #{label( :html, options )}</h#{d}>"
19
+ elsif en > 0
20
+ "<h#{d}>#{label( :html, options )} #{'=' * en}</h#{d}>"
21
+ else
22
+ "<h#{d}>#{label( :html, options )}</h#{d}>"
23
+ end
24
+ end
25
+
26
+ # Text-rendered headings. Should look like this:
27
+ #
28
+ # Heading Level 1
29
+ # ==========================================================================
30
+ #
31
+ # Heading Level 2
32
+ # --------------------------------------------------------------------------
33
+ #
34
+ # - Heading Level 3 --------------------------------------------------------
35
+ #
36
+ # --- Heading Level 4 ------------------------------------------------------
37
+ #
38
+ def to_s( options = {} )
39
+ width = options[:width] || 80
40
+ d = [s.text_value.size, e.text_value.size].min
41
+ sn = s.text_value.size - d
42
+ en = e.text_value.size - d
43
+
44
+ l = if sn > 0
45
+ "#{'=' * sn} #{label( :text, options )}"
46
+ elsif en > 0
47
+ "#{label( :text, options )} #{'=' * en}"
48
+ else
49
+ label( :text, options )
50
+ end
51
+
52
+ case d
53
+ when 1
54
+ "#{l}\n" + ('=' * width)
55
+ when 2
56
+ "#{l}\n" + ('-' * width)
57
+ else
58
+ l = " #{l} "
59
+ h = '-'*width
60
+ h[2*(d-3)+1, l.size] = l # slice substitution
61
+ h
62
+ end
63
+ end
64
+
65
+ def label( format, options = {} )
66
+ case format
67
+ when :html
68
+ l.to_html( options )
69
+ else
70
+ l.to_s( options )
71
+ end
72
+ end
73
+
74
+ #-- defaults ++
75
+ def l #:nodoc:
76
+ nil
77
+ end
78
+ end
79
+ end