org 2009.03.28

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.
@@ -0,0 +1,36 @@
1
+ [96fa8b5 | Sat Mar 28 06:57:31 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
2
+
3
+ * Better rake tasks, now managed by raku
4
+
5
+ [971a989 | Fri Mar 20 05:23:05 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
6
+
7
+ * Spec how lists behave right now
8
+
9
+ [c21d3fb | Sun Mar 15 06:39:58 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
10
+
11
+ * Fix the header spec
12
+
13
+ [93db8d3 | Sun Mar 15 06:35:43 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
14
+
15
+ * Transform input to use \n, add specs for it
16
+
17
+ [9b1ff3a | Sat Feb 21 04:49:40 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
18
+
19
+ * Fix gemspec
20
+
21
+ [bca87be | Sat Feb 21 04:47:40 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
22
+
23
+ * Add the Rakefile
24
+
25
+ [f304ebf | Sat Feb 21 03:40:35 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
26
+
27
+ * Version 2009.02.21
28
+
29
+ [ca4d900 | Thu Jan 01 14:55:47 UTC 2009] Michael Fellinger <m.fellinger@gmail.com>
30
+
31
+ * Org for rakki
32
+
33
+ [3b1f2d2 | Sun Oct 12 08:22:45 UTC 2008] Michael Fellinger <m.fellinger@gmail.com>
34
+
35
+ * Extracted from rakki
36
+
@@ -0,0 +1,29 @@
1
+ CHANGELOG
2
+ MANIFEST
3
+ README.md
4
+ Rakefile
5
+ doc/syntax.org
6
+ lib/org.rb
7
+ lib/org/markup.rb
8
+ lib/org/rule.rb
9
+ lib/org/rules.rb
10
+ lib/org/scope.rb
11
+ lib/org/scope/org_mode.rb
12
+ lib/org/state.rb
13
+ lib/org/stringscanner.rb
14
+ lib/org/to/html.rb
15
+ lib/org/to/toc.rb
16
+ lib/org/token.rb
17
+ lib/org/version.rb
18
+ org.gemspec
19
+ spec/org.rb
20
+ tasks/bacon.rake
21
+ tasks/changelog.rake
22
+ tasks/gem.rake
23
+ tasks/gem_installer.rake
24
+ tasks/grancher.rake
25
+ tasks/install_dependencies.rake
26
+ tasks/manifest.rake
27
+ tasks/rcov.rake
28
+ tasks/release.rake
29
+ tasks/reversion.rake
@@ -0,0 +1,26 @@
1
+ # Org
2
+
3
+ Org provides transformation of a selected subset of org-mode markup for wikis.
4
+
5
+ ## About
6
+
7
+ If you fancy emacs' org-mode and would like to use its power for a wiki based on plain-text files you should check this out.
8
+ Org tries to stay compatible with org-mode, but does not support the full syntax. The most notable features you will find are table of contents, tables, headers, links and simple physical text formatting.
9
+ One feature org-mode doesn't provide (AFAIK) is code highlighting, since the preferred way is to simply link to the file containing the code, but that is a bit impractical in a wiki, so I added this feature.
10
+
11
+ ## Features
12
+
13
+ * Headers
14
+ * Links
15
+ * Tables
16
+ * Text markup
17
+
18
+ ## Dependencies
19
+
20
+ * StringScanner (ruby stdlib)
21
+ * CodeRay (optional)
22
+ * Uv (optional)
23
+
24
+ ## Syntax
25
+
26
+ For a nice intro to the syntax supported by Org please check the [doc/syntax.org] file.
@@ -0,0 +1,28 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/gempackagetask'
4
+ require 'time'
5
+ require 'date'
6
+
7
+ PROJECT_SPECS = Dir['spec/**/*.rb']
8
+ PROJECT_MODULE = 'Org'
9
+
10
+ GEMSPEC = Gem::Specification.new{|s|
11
+ s.name = 'org'
12
+ s.author = "Michael 'manveru' Fellinger"
13
+ s.summary = "transformation of a subset of org-mode markup to html."
14
+ s.description = "transformation of a subset of org-mode markup to html."
15
+ s.email = 'm.fellinger@gmail.com'
16
+ s.homepage = 'http://github.com/manveru/org'
17
+ s.platform = Gem::Platform::RUBY
18
+ s.version = (ENV['PROJECT_VERSION'] || Date.today.strftime("%Y.%m.%d"))
19
+ s.files = `git ls-files`.split("\n").sort
20
+ s.has_rdoc = true
21
+ s.require_path = 'lib'
22
+ }
23
+
24
+ Dir['tasks/*.rake'].each{|f| import(f) }
25
+
26
+ task :default => [:bacon]
27
+
28
+ CLEAN.include('')
@@ -0,0 +1,73 @@
1
+ * OrgMarkup
2
+
3
+ ** Links
4
+
5
+ Internal Links follow the [[Wiki]] [[Wiki][Wiki Wiki]] style, also WikiWords work.
6
+
7
+ To recap:
8
+
9
+ [[Wiki]] is `[[Wiki]]`
10
+ [[Wiki][Wiki]] is `[[Wiki][Wiki]]`
11
+ WikiWords was `WikiWords`
12
+
13
+ You can easily plug into the handling of links and implement things like `[[flash:screencast-blog][My Screencast about Blogging]]`, but by default there will be no link formatting until I can find a nice set of defaults.
14
+
15
+ ** Lists
16
+
17
+ * Lists start with a `*` after one or more spaces from the beginning of a line.
18
+ * Nested lists are maybe not working correctly yet.
19
+
20
+ ** Headers
21
+
22
+ Headers are written as follows:
23
+
24
+ {{{
25
+ * h1
26
+ ** h2
27
+ *** h3
28
+ **** h4
29
+ ***** h5
30
+ ****** h6
31
+ }}}
32
+
33
+ ** Code
34
+
35
+ You can start a code block with `{{{` and end it with `}}}`, each on its own line. For code inside a line please use =`backticks`=.
36
+
37
+ {{{
38
+ This is a line of code
39
+ }}}
40
+
41
+
42
+ {{{ ruby
43
+ puts "This is a line of Ruby code"
44
+ }}}
45
+
46
+ You may also use `c`, `delphi`, `html`, `ezamar`, `nitro_xhtml`, `plaintext`, `rhtml`, or `xml`
47
+
48
+ ** Text formatting
49
+
50
+ /italic/ is `/italic/`
51
+ *bold* is `*bold*`
52
+ _underline_ is `_underline_`
53
+ +strikethrough+ is `+strikethrough+`
54
+ ~blockquote~ is `~blockquote~`
55
+ =code= is `=code=`
56
+ and `code` is =`code`=
57
+ last, but not least, there's also `----` the horizontal rule
58
+
59
+ ----
60
+
61
+ ** Tables
62
+
63
+ |--------------+-------------------------+----------------|
64
+ | Name | Telephone | Room |
65
+ |--------------+-------------------------+----------------|
66
+ | Mr. X | 777-777 | 42 |
67
+ | Mrs. Y | 888-888 | 21 |
68
+ | see? | tables | are |
69
+ | easy | enough | eh? |
70
+ |--------------+-------------------------+----------------|
71
+ | you can even | use separating elements | but they won't |
72
+ | show up | in the | endresult. |
73
+ |--------------+-------------------------+----------------|
@@ -0,0 +1,28 @@
1
+ require 'strscan'
2
+ require 'pp'
3
+
4
+ $LOAD_PATH.unshift File.dirname(__FILE__)
5
+
6
+ module Org
7
+ module_function
8
+
9
+ def escape_html(string)
10
+ string.to_s.gsub("&", "&amp;").
11
+ gsub("<", "&lt;").
12
+ gsub(">", "&gt;").
13
+ gsub("'", "&#39;").
14
+ gsub('"', "&quot;")
15
+ end
16
+ end
17
+
18
+ require 'org/version'
19
+ require 'org/stringscanner'
20
+ require 'org/markup'
21
+ require 'org/state'
22
+ require 'org/scope'
23
+ require 'org/token'
24
+ require 'org/rule'
25
+
26
+ require 'org/scope/org_mode'
27
+ require 'org/to/html'
28
+ require 'org/to/toc'
@@ -0,0 +1,34 @@
1
+ module Org
2
+ class Markup
3
+ attr_accessor :string
4
+
5
+ def initialize(file = nil)
6
+ self.string = File.read(file) if file
7
+ end
8
+
9
+ def apply(string = @string)
10
+ self.string = string
11
+
12
+ parent = RootToken.new(:root, nil)
13
+ scanner = StringScanner.new(self.string)
14
+ state = State.new(@scope, parent, scanner)
15
+
16
+ until scanner.eos?
17
+ pos = scanner.pos
18
+ state.step
19
+ raise("Didn't move: %p" % scanner) if pos == scanner.pos
20
+ end
21
+
22
+ return parent
23
+ end
24
+
25
+ def scope(name, options = {}, &block)
26
+ @scope = Scope.new(name, options)
27
+ yield(@scope)
28
+ end
29
+
30
+ def string=(string)
31
+ @string = string.gsub(/\r\n|\r/, "\n")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ module Org
2
+ class Rule
3
+ DEFAULT = {
4
+ :bol => false,
5
+ :start => nil,
6
+ :end => nil,
7
+ :unscan => false,
8
+ }
9
+
10
+ attr_accessor :name, :regex
11
+
12
+ def initialize(name, regex, options = {}, &block)
13
+ @name, @regex, @block = name, regex, block
14
+ @options = DEFAULT.merge(options)
15
+ end
16
+
17
+ def match(state)
18
+ scope, parent, scanner = state.scope, state.parent, state.scanner
19
+ return if @options[:bol] and not scanner.bol?
20
+
21
+ return false unless scanner.scan(@regex)
22
+ scanner.unscan if @options[:unscan]
23
+
24
+ name = @options[:tag] || @name
25
+ token = Token.new(name, scanner.captures, &@block)
26
+ return true if @options[:ignore]
27
+
28
+ if mode = @options[:start]
29
+ # puts "Start #{mode}"
30
+ state.scope = mode.is_a?(Scope) ? mode : scope.scopes[mode]
31
+ parent << token
32
+ state.parent = token
33
+ elsif mode = @options[:end]
34
+ # puts "End #{mode}"
35
+ state.parent = parent.parent
36
+ state.scope = scope.parent
37
+ else
38
+ parent << token
39
+ return true
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,108 @@
1
+ require 'org'
2
+
3
+ # rs = RuleSet.new("~/c/innate/example/app/wiki/pages/Home.owl")
4
+ rs = OrgMarkup.new("test.org")
5
+
6
+ rs.scope(:block, :indent => true) do |block|
7
+ block.rule :header, /(\*+)\s+(.*)\n/, :bol => true
8
+ block.rule :table, /\|([^|]+)/, :bol => true, :start => :table, :unscan => true
9
+ block.rule :br, /\n/
10
+ block.rule :p, /(.)/, :bol => true, :start => :inline, :unscan => true
11
+ block.rule :space, /\s/
12
+
13
+ inline_rules = lambda do |parent|
14
+ # * You can make words *bold*, /italic/, _underlined_, `=code=' and
15
+ # `~verbatim~', and, if you must, `+strikethrough+'. Text in the
16
+ # code and verbatim string is not processed for org-mode specific
17
+ # syntax, it is exported verbatim.
18
+ parent.rule :a, /\b([A-Z]\w+[A-Z]\w+)/
19
+ parent.rule :text, /([A-Za-z0-9,. ]+)/
20
+ # [[file:foo][My file foo]]
21
+ parent.rule :a, /\[\[([^:\]]+):([^\]]+)\]\[([^\]]+)\]\]/
22
+ # [[http://go.to/][Go to]]
23
+ parent.rule :a, /\[\[([^\]]+)\]\[([^\]]+)\]\]/
24
+ # [[file:foo]]
25
+ parent.rule :a, /\[\[([^:\]]+):([^\]]+)\]\]/
26
+ # [[foo]]
27
+ parent.rule :a, /\[\[([^\]]+)\]\]/
28
+ parent.rule :italic, /\/([^\/]+)\//
29
+ parent.rule :bold, /\*([^*]+)\*/, :tag => :b
30
+ parent.rule :underline, /_([^_]+)_/
31
+ parent.rule :strikethrough, /\+([^+]+)\+/
32
+ parent.rule :verbatim, /~([^~]+)~/
33
+ parent.rule :code, /\=([^=]+)\=/
34
+ end
35
+
36
+ block.scope(:inline, :indent => false) do |inline|
37
+ inline.apply(&inline_rules)
38
+ inline.rule :text, /(.)/
39
+ inline.rule :close, /\n\n+/, :end => :inline
40
+ inline.rule :br, /\n/
41
+ end
42
+
43
+ block.scope(:table, :indent => true) do |table|
44
+ # | name | telelphone | room |
45
+ # |--------+------------+------|
46
+ # | Mr. X | 777-777 | 42 |
47
+ # | Mrs. Y | 888-888 | 21 |
48
+
49
+ table.rule :tr, /\|([^|]+)/, :bol => true, :unscan => true, :start => :tr
50
+ table.rule :close, /\n/, :end => :table
51
+
52
+ table.scope(:tr, :indent => true) do |tr|
53
+ tr.rule :table_separator, /\|[+-]+\|/
54
+ tr.rule :close, /\|\n/, :end => :tr
55
+ tr.rule :close, /\n/, :end => :tr
56
+ tr.rule :td, /\|/, :start => :td
57
+
58
+ tr.scope :td do |td|
59
+ td.apply(&inline_rules)
60
+ td.rule :space, /([\t ]+)/
61
+ td.rule :text, /([^|])/
62
+ td.rule :close, /\|/, :end => :td, :unscan => true
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ require 'pp'
69
+
70
+ class OrgMarkup
71
+ module ToHtml
72
+ def html_link(leader, href = nil, title = nil)
73
+ case leader
74
+ when 'rss'
75
+ link_rss(href, title)
76
+ when 'file'
77
+ link_file(href, title)
78
+ when 'http', 'https', 'ftp'
79
+ link_out("#{leader}:#{href}", title)
80
+ else
81
+ link_in(leader, href)
82
+ end
83
+ end
84
+
85
+ # Respond to [[rss:href]] and [[rss:href][title]]
86
+ def link_rss(href, title)
87
+ "<rss %p %p>" % [href, title]
88
+ ''
89
+ end
90
+
91
+ # Respond to [[file:href]] and [[file:href][title]]
92
+ def link_file(href, title)
93
+ "<file %p %p>" % [href, title]
94
+ ''
95
+ end
96
+
97
+ def link_out(href, title)
98
+ "<out %p %p>" % [href, title]
99
+ tag(:a, title || href, :href => href)
100
+ end
101
+
102
+ # Respond to [[name]] and [[name][title]]
103
+ def link_in(href, title)
104
+ "<wiki %p %p>" % [href, title]
105
+ tag(:a, title || href, :href => "/#{href}")
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,35 @@
1
+ module Org
2
+ class Scope
3
+ attr_accessor :parent, :name, :scopes
4
+
5
+ def initialize(name, options = {})
6
+ @rules = []
7
+ @name, @options = name, options
8
+ @scopes = {}
9
+ end
10
+
11
+ def scope(name, options = {}, &block)
12
+ scope = Scope.new(name, options)
13
+ scope.parent = self
14
+ yield @scopes[name] = scope
15
+ end
16
+
17
+ def rule(name, regex, options = {})
18
+ @rules << Rule.new(name, regex, options)
19
+ end
20
+
21
+ def apply
22
+ yield(self)
23
+ end
24
+
25
+ def step(state)
26
+ @rules.find do |rule|
27
+ rule.match(state)
28
+ end
29
+ end
30
+
31
+ def inspect
32
+ "<Scope #{name}>"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,93 @@
1
+ module Org
2
+ OrgMode = Markup.new
3
+ eol = /\n/ # we keep this simple and convert the input string instead
4
+
5
+ OrgMode.scope(:block, :indent => true) do |block|
6
+ block.rule :header, /(\*+)\s+(.*)(#{eol}|\z)/, :bol => true
7
+ block.rule :table, /\|([^|]+)/, :bol => true, :start => :table, :unscan => true
8
+ block.rule :ul, /[ \t]+[\*\+\-]+\s*(.*)/, :start => :ul, :unscan => true, :bol => true
9
+ block.rule :ol, /[ \t]+[0-9]+[\.\)]\s*(.*)/, :start => :ol, :unscan => true, :bol => true
10
+ block.rule :br, eol
11
+ block.rule :p, /(.)/, :bol => true, :start => :inline, :unscan => true
12
+ block.rule :space, /\s/
13
+
14
+ inline_rules = lambda do |parent|
15
+ # * You can make words *bold*, /italic/, _underlined_, `=code=' and
16
+ # `~verbatim~', and, if you must, `+strikethrough+'. Text in the
17
+ # code and verbatim string is not processed for org-mode specific
18
+ # syntax, it is exported verbatim.
19
+ parent.rule :a, /\b([A-Z]\w+[A-Z]\w+)/
20
+ parent.rule :text, /([A-Za-z0-9,. ]+)/
21
+ # parent.rule :text, /(\/\/)/
22
+ parent.rule :a, /\[\[([^\]]+)\]\[([^\]]+)\]\]/
23
+ parent.rule :a, /\[\[(.+?)\]\]/
24
+ parent.rule :italic, /\/([^\/ ]+)\//, :tag => :i
25
+ parent.rule :bold, /\*([^* ]+)\*/, :tag => :b
26
+ parent.rule :underline, /_([^_ ]+)_/, :tag => :u
27
+ parent.rule :strikethrough, /\+([^+ ]+)\+/, :tag => :s
28
+ parent.rule :blockquote, /~([^~ ]+)~/
29
+ parent.rule :code, /\=([^= ]+)\=/
30
+ parent.rule :code, /`([^`]+)`/
31
+ parent.rule :hr, /---+/, :bol => true
32
+ end
33
+
34
+ block.scope :ul do |ul|
35
+ ul.rule :li, /[ \t]+[\*\+\-]+\s*/, :start => :li, :bol => true
36
+ ul.rule :close, eol, :end => :ul
37
+ ul.rule :close, /(.)/, :end => :ul, :unscan => true
38
+
39
+ ul.scope :li do |li|
40
+ li.apply(&inline_rules)
41
+ li.rule :text, /(.)/
42
+ li.rule :ul, /[ \t]+[\*\+\-]+\s*/, :start => ul, :bol => true
43
+ li.rule :close, eol, :end => :li
44
+ end
45
+ end
46
+
47
+ block.scope :ol do |ol|
48
+ ol.rule :li, /[ \t]+[0-9]+[\.\)]\s*/, :start => :li, :bol => true
49
+ # ol.rule :ul, /[ \t]+[\*\-\+]+\s*/, :start => :ul, :bol => true, :unscan => true
50
+ ol.rule :close, eol, :end => :ol
51
+ ol.rule :close, /(.)/, :end => :ol, :unscan => true
52
+
53
+ ol.scope :li do |li|
54
+ li.apply(&inline_rules)
55
+ li.rule :text, /(.)/
56
+ li.rule :close, eol, :end => :li
57
+ end
58
+ end
59
+
60
+ block.scope(:inline, :indent => false) do |inline|
61
+ inline.apply(&inline_rules)
62
+ inline.rule :highlight, /\{\{\{[\t ]*(\S+)#{eol}(.*?)#{eol}\}\}\}/m
63
+ inline.rule :highlight, /\{\{\{#{eol}(.*?)#{eol}\}\}\}/m
64
+ inline.rule :text, /(.)/
65
+ inline.rule :close, /#{eol}#{eol}+/, :end => :inline
66
+ inline.rule :br, eol
67
+ end
68
+
69
+ block.scope(:table, :indent => true) do |table|
70
+ # | name | telelphone | room |
71
+ # |--------+------------+------|
72
+ # | Mr. X | 777-777 | 42 |
73
+ # | Mrs. Y | 888-888 | 21 |
74
+
75
+ table.rule :tr, /\|([^|]+)/, :bol => true, :unscan => true, :start => :tr
76
+ table.rule :close, eol, :end => :table
77
+
78
+ table.scope(:tr, :indent => true) do |tr|
79
+ tr.rule :table_separator, /\|[+-]+\|/, :ignore => true
80
+ tr.rule :close, /\|#{eol}/, :end => :tr
81
+ tr.rule :close, eol, :end => :tr
82
+ tr.rule :td, /\|/, :start => :td
83
+
84
+ tr.scope :td do |td|
85
+ td.apply(&inline_rules)
86
+ td.rule :space, /([\t ]+)/
87
+ td.rule :text, /([^|])/
88
+ td.rule :close, /\|/, :end => :td, :unscan => true
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,12 @@
1
+ module Org
2
+ class State < Struct.new(:scope, :parent, :scanner)
3
+ def step
4
+ loop do
5
+ # before = scanner.string[0...scanner.pos][-25, 25]
6
+ # after = scanner.string[scanner.pos..-1][0, 50]
7
+ # p "%40s@%40s" % [before, after]
8
+ break unless scope.step(self)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require 'strscan'
2
+
3
+ module Org
4
+ # Adding some comfort
5
+ class StringScanner < ::StringScanner
6
+ # Equivalent to Regexp#captures, returns Array of all matches
7
+ def captures
8
+ n = 0
9
+ found = []
10
+ while n += 1
11
+ return found unless element = self[n]
12
+ found << element
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,91 @@
1
+ module Org
2
+ class RootToken < Token
3
+ # little optimization, avoid check for root
4
+ def to_html
5
+ @childs.map{|child| child.to_html }.join
6
+ end
7
+ end
8
+
9
+ module ToHtml
10
+ def to_html
11
+ method = "html_#{@name}"
12
+
13
+ if respond_to?(method)
14
+ send(method)
15
+ elsif @childs.empty?
16
+ Tag.new(name, values)
17
+ else
18
+ Tag.new(name, values){ @childs.map{|c| c.to_html }.join }
19
+ end
20
+ end
21
+
22
+ def html_text
23
+ Org.escape_html(values.join)
24
+ end
25
+
26
+ # unify toc_id somwhere?
27
+ def html_header
28
+ level, text = values[0].size, values[1]
29
+ id = respond_to?(:toc_id) ? toc_id : text.gsub(/\W/, '-').squeeze('-').downcase
30
+ Tag.new("h#{level}", text, :id => id)
31
+ end
32
+
33
+ def html_space
34
+ ' '
35
+ end
36
+
37
+ # TODO: find a simple way of caching highlighted code from Uv,
38
+ # gives us much more possibilities in highlighting compared
39
+ # to coderay, but is also _really_ slow.
40
+ def html_highlight
41
+ language, code = *values
42
+ require 'coderay'
43
+ language = 'nitro_xhtml' if language == 'ezamar'
44
+
45
+ case language
46
+ when *%w[ruby c delphi html nitro_xhtml plaintext rhtml xml]
47
+ tokens = CodeRay.scan(code, language)
48
+ html = tokens.html(:wrap => :div)
49
+ when *%w[diff]
50
+ require 'uv'
51
+ Uv.parse(code, output = 'xhtml', syntax_name = language, line_numbers = false, render_style = 'amy', headers = false)
52
+ else
53
+ code = language if not code or code.strip.empty?
54
+ html = tag(:pre, code)
55
+ end
56
+ end
57
+
58
+ def tag(*args)
59
+ Tag.new(*args)
60
+ end
61
+ end
62
+
63
+ # Extracted from Ramaze Gestalt
64
+ class Tag
65
+ def initialize(name, value, args = {}, &block)
66
+ @name, @value, @args, @block = name, value, args, block
67
+ end
68
+
69
+ def to_s
70
+ @out = ''
71
+ build_tag(@name, @args, @value, &@block)
72
+ @out
73
+ end
74
+
75
+ def build_tag(name, attr = {}, text = [])
76
+ @out << "<#{name}"
77
+ @out << attr.map{|k,v| %[ #{k}="#{Org.escape_html(v)}"] }.join
78
+ if text != [] or block_given?
79
+ @out << ">"
80
+ @out << Org.escape_html([text].join)
81
+ if block_given?
82
+ text = yield
83
+ @out << text.to_str if text != @out and text.respond_to?(:to_str)
84
+ end
85
+ @out << "</#{name}>"
86
+ else
87
+ @out << ' />'
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,51 @@
1
+ module Org
2
+ class RootToken
3
+ def to_toc
4
+ found = @childs.map{|child| child.to_toc }.flatten.compact
5
+
6
+ out = []
7
+ nest = 0
8
+
9
+ while token = found.shift
10
+ level, text = *token.values
11
+ level = level.size
12
+
13
+ if level > nest
14
+ out << '<ol>'
15
+ elsif level < nest
16
+ out << '</ol>'
17
+ end
18
+ nest = level
19
+
20
+ out << "<li>#{token.toc_link}</li>"
21
+ end
22
+
23
+ nest.times do
24
+ out << '</ol>'
25
+ end
26
+
27
+ out
28
+ end
29
+ end
30
+
31
+ module ToToc
32
+ TOC_ENTRIES = [:header]
33
+
34
+ def to_toc
35
+ case @name
36
+ when *TOC_ENTRIES
37
+ self
38
+ else
39
+ @childs.map{|child| child.to_toc }
40
+ end
41
+ end
42
+
43
+ def toc_link
44
+ tag(:a, values[1], :href => "##{toc_id}")
45
+ end
46
+
47
+ def toc_id
48
+ values[1].gsub(/\W/, '-').squeeze('-').downcase
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,20 @@
1
+ module Org
2
+ class Token
3
+ attr_accessor :name, :values, :options, :block, :childs, :parent
4
+
5
+ def initialize(name, values, options = {}, &block)
6
+ @name, @values, @options, @block = name, values, options, block
7
+ @childs = []
8
+ end
9
+
10
+ def <<(token)
11
+ token.parent = self
12
+ @childs << token
13
+ end
14
+
15
+ def pretty_inspect
16
+ {[name, values] => childs}.pretty_inspect
17
+ end
18
+ alias inspect pretty_inspect
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Org
2
+ VERSION = "2009.03.28"
3
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{org}
5
+ s.version = "2009.03.28"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael 'manveru' Fellinger"]
9
+ s.date = %q{2009-03-28}
10
+ s.description = %q{transformation of a subset of org-mode markup to html.}
11
+ s.email = %q{m.fellinger@gmail.com}
12
+ s.files = ["CHANGELOG", "MANIFEST", "README.md", "Rakefile", "doc/syntax.org", "lib/org.rb", "lib/org/markup.rb", "lib/org/rule.rb", "lib/org/rules.rb", "lib/org/scope.rb", "lib/org/scope/org_mode.rb", "lib/org/state.rb", "lib/org/stringscanner.rb", "lib/org/to/html.rb", "lib/org/to/toc.rb", "lib/org/token.rb", "lib/org/version.rb", "org.gemspec", "spec/org.rb", "tasks/bacon.rake", "tasks/changelog.rake", "tasks/gem.rake", "tasks/gem_installer.rake", "tasks/grancher.rake", "tasks/install_dependencies.rake", "tasks/manifest.rake", "tasks/rcov.rake", "tasks/release.rake", "tasks/reversion.rake"]
13
+ s.has_rdoc = true
14
+ s.homepage = %q{http://github.com/manveru/org}
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.3.1}
17
+ s.summary = %q{transformation of a subset of org-mode markup to html.}
18
+
19
+ if s.respond_to? :specification_version then
20
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
21
+ s.specification_version = 2
22
+
23
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
24
+ else
25
+ end
26
+ else
27
+ end
28
+ end
@@ -0,0 +1,92 @@
1
+ require 'lib/org'
2
+ require 'org/scope/org_mode'
3
+ require 'org/to/html'
4
+
5
+ module Org
6
+ class Token
7
+ include ToHtml
8
+ include ToToc
9
+
10
+ def html_a(*args)
11
+ link, desc = *values
12
+ href = link =~ /^https?:\/\// ? link : "/#{link}"
13
+ tag(:a, (desc || link), :href => href)
14
+ end
15
+ end
16
+ end
17
+
18
+ require 'bacon'
19
+ require 'hpricot'
20
+
21
+ Bacon.extend(Bacon::TestUnitOutput)
22
+ Bacon.summary_on_exit
23
+
24
+ describe Org::Markup do
25
+ def t(string) # short for transform
26
+ Org::OrgMode.apply(string).to_html
27
+ end
28
+
29
+ should 'markup headers' do
30
+ t("* header" ).should == '<h1 id="header">header</h1>'
31
+ t("** header" ).should == '<h2 id="header">header</h2>'
32
+ t("*** header" ).should == '<h3 id="header">header</h3>'
33
+ t("**** header" ).should == '<h4 id="header">header</h4>'
34
+ t("***** header" ).should == '<h5 id="header">header</h5>'
35
+ t("****** header").should == '<h6 id="header">header</h6>'
36
+ end
37
+
38
+ should 'markup inline' do
39
+ t('*foo*').should == '<p><b>foo</b></p>'
40
+ t('/foo/').should == '<p><i>foo</i></p>'
41
+ t('_foo_').should == '<p><u>foo</u></p>'
42
+ t('+foo+').should == '<p><s>foo</s></p>'
43
+ t('~foo~').should == '<p><blockquote>foo</blockquote></p>'
44
+ t('=foo=').should == '<p><code>foo</code></p>'
45
+ end
46
+
47
+ should 'markup table' do
48
+ table = Hpricot(t("|name|address|\n|manveru|home|\n|gojira|tokyo|\n")).at(:table)
49
+ (table/:tr).map{|tr| (tr/:td).map{|td| td.inner_text } }.
50
+ should == [%w[name address], %w[manveru home], %w[gojira tokyo]]
51
+ end
52
+
53
+ should 'markup link' do
54
+ t('[[home]]').should == '<p><a href="/home">home</a></p>'
55
+ t('[[home][Home]]').should == '<p><a href="/home">Home</a></p>'
56
+ t('[[http://go.to/]]').should == '<p><a href="http://go.to/">http://go.to/</a></p>'
57
+ t('[[http://go.to/][Go to]]').should == '<p><a href="http://go.to/">Go to</a></p>'
58
+ end
59
+
60
+ should 'work with \r, \n, and \n\r' do
61
+ t("a\nb").should == '<p>a<br />b</p>'
62
+ t("a\r\nb").should == t("a\nb")
63
+ t("a\rb").should == t("a\nb")
64
+ end
65
+
66
+ should 'markup unorderd lists' do
67
+ t(" * one").should == '<ul><li>one</li></ul>'
68
+ t(" * one\n * two").should == '<ul><li>one</li><li>two</li></ul>'
69
+ t(" * one
70
+ * two
71
+ * three").should == '<ul><li>one</li><li>two</li><li>three</li></ul>'
72
+ t(" + one").should == '<ul><li>one</li></ul>'
73
+ t(" - one").should == '<ul><li>one</li></ul>'
74
+ end
75
+
76
+ should 'markup ordered lists' do
77
+ t(" 1. one").should == '<ol><li>one</li></ol>'
78
+ t(" 1) one").should == '<ol><li>one</li></ol>'
79
+ t(" 1. one\n 2. two").should == '<ol><li>one</li><li>two</li></ol>'
80
+ end
81
+
82
+ should 'markup nested lists' do
83
+ t(" * one\n + nest1\n + nest2\n * two\n").should ==
84
+ '<ul><li>one</li><ul><li>nest1</li><li>nest2</li></ul></ul>'
85
+ t(" 1. one\n + nest1\n + nest2\n 2. two\n").should ==
86
+ '<ol><li>one</li><ul><li>nest1</li><li>nest2</li></ul></ol>'
87
+ end
88
+
89
+ should 'markup inline in lists' do
90
+ t(' * first _foo_ /bar/').should == '<ul><li>first <u>foo</u> <i>bar</i></li></ul>'
91
+ end
92
+ end
@@ -0,0 +1,49 @@
1
+ desc 'Run all bacon specs with pretty output'
2
+ task :bacon => :install_dependencies do
3
+ require 'open3'
4
+ require 'scanf'
5
+
6
+ specs = PROJECT_SPECS
7
+
8
+ some_failed = false
9
+ total = specs.size
10
+ len = specs.map{|s| s.size }.sort.last
11
+ tt = ta = tf = te = 0
12
+
13
+ red, yellow, green = "\e[31m%s\e[0m", "\e[33m%s\e[0m", "\e[32m%s\e[0m"
14
+ left_format = "%4d/%d: %-#{len + 11}s"
15
+ spec_format = "%d specifications (%d requirements), %d failures, %d errors"
16
+
17
+ specs.each_with_index do |spec, idx|
18
+ print(left_format % [idx + 1, total, spec])
19
+
20
+ Open3.popen3(RUBY, spec) do |sin, sout, serr|
21
+ out = sout.read
22
+ err = serr.read
23
+
24
+ ran = false
25
+
26
+ out.each_line do |line|
27
+ tests, assertions, failures, errors = all = line.scanf(spec_format)
28
+ next unless all.any?
29
+ ran = true
30
+ tt += tests; ta += assertions; tf += failures; te += errors
31
+
32
+ if tests == 0 || failures + errors > 0
33
+ puts((red % spec_format) % all)
34
+ puts out
35
+ puts err
36
+ else
37
+ puts((green % "%6d passed") % tests)
38
+ end
39
+
40
+ break
41
+ end
42
+
43
+ puts(yellow % " skipped") unless ran
44
+ end
45
+ end
46
+
47
+ puts(spec_format % [tt, ta, tf, te])
48
+ exit 1 if some_failed
49
+ end
@@ -0,0 +1,18 @@
1
+ desc 'update changelog'
2
+ task :changelog do
3
+ File.open('CHANGELOG', 'w+') do |changelog|
4
+ `git log -z --abbrev-commit`.split("\0").each do |commit|
5
+ next if commit =~ /^Merge: \d*/
6
+ ref, author, time, _, title, _, message = commit.split("\n", 7)
7
+ ref = ref[/commit ([0-9a-f]+)/, 1]
8
+ author = author[/Author: (.*)/, 1].strip
9
+ time = Time.parse(time[/Date: (.*)/, 1]).utc
10
+ title.strip!
11
+
12
+ changelog.puts "[#{ref} | #{time}] #{author}"
13
+ changelog.puts '', " * #{title}"
14
+ changelog.puts '', message.rstrip if message
15
+ changelog.puts
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'rake/gempackagetask'
2
+
3
+ task :gemspec => [:manifest, :changelog] do
4
+ gemspec_file = "#{GEMSPEC.name}.gemspec"
5
+ File.open(gemspec_file, 'w+'){|gs| gs.puts(GEMSPEC.to_ruby) }
6
+ end
7
+
8
+ desc "package and install from gemspec"
9
+ task :install => [:gemspec] do
10
+ sh "gem build #{GEMSPEC.name}.gemspec"
11
+ sh "gem install #{GEMSPEC.name}-#{GEMSPEC.version}.gem"
12
+ end
13
+
14
+ desc "uninstall the gem"
15
+ task :uninstall => [:clean] do
16
+ sh %{gem uninstall -x #{GEMSPEC.name}}
17
+ end
18
+
19
+ Rake::GemPackageTask.new(GEMSPEC) do |p|
20
+ p.need_tar = true
21
+ p.need_zip = true
22
+ end
@@ -0,0 +1,76 @@
1
+ task :gem_installer do
2
+ class GemInstaller
3
+ def initialize(options = {}, &block)
4
+ @gems = []
5
+ @options = options
6
+
7
+ run(&block)
8
+ end
9
+
10
+ def run(&block)
11
+ instance_eval(&block) if block_given?
12
+ end
13
+
14
+ def gem(name, version = nil, options = {})
15
+ if version.respond_to?(:merge!)
16
+ options = version
17
+ else
18
+ options[:version] = version
19
+ end
20
+
21
+ @gems << [name, options]
22
+ end
23
+
24
+ def setup_gemspec(gemspec)
25
+ gemspec.dependencies.each do |dependency|
26
+ dependency.version_requirements.as_list.each do |version|
27
+ gem(dependency.name, version)
28
+ end
29
+ end
30
+
31
+ setup
32
+ end
33
+
34
+ def setup
35
+ require 'rubygems'
36
+ require 'rubygems/dependency_installer'
37
+
38
+ @gems.each do |name, options|
39
+ setup_gem(name, options)
40
+ end
41
+ end
42
+
43
+ def setup_gem(name, options, try_install = true)
44
+ print "activating #{name} ... "
45
+ Gem.activate(name, *[options[:version]].compact)
46
+ require(options[:lib] || name)
47
+ puts "success."
48
+ rescue LoadError => error
49
+ puts error
50
+ install_gem(name, options) if try_install
51
+ setup_gem(name, options, try_install = false)
52
+ end
53
+
54
+ def install_gem(name, options)
55
+ installer = Gem::DependencyInstaller.new(options)
56
+
57
+ temp_argv(options[:extconf]) do
58
+ print "Installing #{name} ... "
59
+ installer.install(name, options[:version])
60
+ puts "done."
61
+ end
62
+ end
63
+
64
+ def temp_argv(extconf)
65
+ if extconf ||= @options[:extconf]
66
+ old_argv = ARGV.clone
67
+ ARGV.replace(extconf.split(' '))
68
+ end
69
+
70
+ yield
71
+
72
+ ensure
73
+ ARGV.replace(old_argv) if extconf
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ begin
2
+ require 'grancher/task'
3
+
4
+ Grancher::Task.new do |g|
5
+ g.branch = 'gh-pages'
6
+ g.push_to = 'origin'
7
+ g.message = 'Updated website'
8
+ g.directory 'ydoc', 'doc'
9
+ end
10
+ rescue LoadError
11
+ # oh well :)
12
+ end
@@ -0,0 +1,6 @@
1
+ desc 'install dependencies'
2
+ task :install_dependencies => [:gem_installer] do
3
+ GemInstaller.new do
4
+ setup_gemspec(GEMSPEC)
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ desc 'update manifest'
2
+ task :manifest do
3
+ File.open('MANIFEST', 'w+'){|io| io.puts(*GEMSPEC.files) }
4
+ end
@@ -0,0 +1,19 @@
1
+ desc 'code coverage'
2
+ task :rcov => :clean do
3
+ specs = Dir['spec/innate/**/*.rb']
4
+ specs -= Dir['spec/innate/cache/common.rb']
5
+
6
+ # we ignore adapter as this has extensive specs in rack already.
7
+ ignore = %w[ gem rack bacon innate/adapter\.rb ]
8
+ ignore << 'fiber\.rb' if RUBY_VERSION < '1.9'
9
+
10
+ ignored = ignore.join(',')
11
+
12
+ cmd = "rcov --aggregate coverage.data --sort coverage -t --%s -x '#{ignored}' %s"
13
+
14
+ while spec = specs.shift
15
+ puts '', "Gather coverage for #{spec} ..."
16
+ html = specs.empty? ? 'html' : 'no-html'
17
+ sh(cmd % [html, spec])
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ desc 'publish to github'
2
+ task :release => [:reversion, :gemspec] do
3
+ name, version = GEMSPEC.name, GEMSPEC.version
4
+
5
+ sh("git add MANIFEST CHANGELOG #{name}.gemspec lib/#{name}/version.rb")
6
+
7
+ puts "I added the relevant files, you can now run:", ''
8
+ puts "git commit -m 'Version #{version}'"
9
+ puts "git tag -a -m '#{version}' '#{version}'"
10
+ puts "git push"
11
+ puts
12
+ end
@@ -0,0 +1,8 @@
1
+ desc "update version.rb"
2
+ task :reversion do
3
+ File.open("lib/#{GEMSPEC.name}/version.rb", 'w+') do |file|
4
+ file.puts("module #{PROJECT_MODULE}")
5
+ file.puts(' VERSION = %p' % GEMSPEC.version.to_s)
6
+ file.puts('end')
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: org
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 2009
7
+ - 3
8
+ - 28
9
+ version: 2009.03.28
10
+ platform: ruby
11
+ authors:
12
+ - Michael 'manveru' Fellinger
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-03-28 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: transformation of a subset of org-mode markup to html.
22
+ email: m.fellinger@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - CHANGELOG
31
+ - MANIFEST
32
+ - README.md
33
+ - Rakefile
34
+ - doc/syntax.org
35
+ - lib/org.rb
36
+ - lib/org/markup.rb
37
+ - lib/org/rule.rb
38
+ - lib/org/rules.rb
39
+ - lib/org/scope.rb
40
+ - lib/org/scope/org_mode.rb
41
+ - lib/org/state.rb
42
+ - lib/org/stringscanner.rb
43
+ - lib/org/to/html.rb
44
+ - lib/org/to/toc.rb
45
+ - lib/org/token.rb
46
+ - lib/org/version.rb
47
+ - org.gemspec
48
+ - spec/org.rb
49
+ - tasks/bacon.rake
50
+ - tasks/changelog.rake
51
+ - tasks/gem.rake
52
+ - tasks/gem_installer.rake
53
+ - tasks/grancher.rake
54
+ - tasks/install_dependencies.rake
55
+ - tasks/manifest.rake
56
+ - tasks/rcov.rake
57
+ - tasks/release.rake
58
+ - tasks/reversion.rake
59
+ has_rdoc: true
60
+ homepage: http://github.com/manveru/org
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options: []
65
+
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.7
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: transformation of a subset of org-mode markup to html.
91
+ test_files: []
92
+