pax_global_header 0000666 0000000 0000000 00000000064 12105711076 0014512 g ustar 00root root 0000000 0000000 52 comment=018286054861ed13cc0e5ecddf450f6a995bdeb8 ruby-org-0.8.0/ 0000775 0000000 0000000 00000000000 12105711076 0013265 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/.gitignore 0000664 0000000 0000000 00000000047 12105711076 0015256 0 ustar 00root root 0000000 0000000 *.tmproj /util/gen-special-replace.elc ruby-org-0.8.0/.travis.yml 0000664 0000000 0000000 00000000227 12105711076 0015377 0 ustar 00root root 0000000 0000000 language: ruby rvm: - 1.9.3 - 1.9.2 - 1.8.7 - jruby-18mode - jruby-19mode - rbx-18mode - rbx-19mode - ruby-head - jruby-head - ree ruby-org-0.8.0/Gemfile 0000664 0000000 0000000 00000000267 12105711076 0014565 0 ustar 00root root 0000000 0000000 source :rubygems gemspec group :development, :test do gem 'rake' gem 'rspec' gem 'tilt' end group :coderay do gem 'coderay' end group :pygments do gem 'pygments.rb' end ruby-org-0.8.0/History.txt 0000664 0000000 0000000 00000011522 12105711076 0015470 0 ustar 00root root 0000000 0000000 == 0.8.0 / 2013-02-10 * A lot of refactoring work and bugfixes contributed by vonavi (many thanks!) * Raw HTML is supported with #+html * Code indentation for code blocks is fixed now * Support for definition lists is improved * Bugfix for when including headlines in center and quote blocks. * Indentation of HTML output improved * Improvements to entities support for Textile and HTML outputs == 0.7.2 / 2012-10-07 * Many fixes to the regular expressions used for emphasis, contributed by [[http://github.com/vonavi][vonavi]] * Bug fix for when a table starts with a headline, thanks to [[http://github/til][til]] * Asterisk can be used for definition lists too * Use text lexer as default option for Pygments and Coderay when no language is specified == 0.7.1 / 2012-08-04 * Make source code blocks from lisp dialects use Pygments scheme lexer * Bugfix: Make Coderay fallback to text lexer when unsupported lang is set == 0.7.0 / 2012-07-08 * Highlight source code blocks using Pygments or CodeRay when available == 0.6.4 / 2012-07-08 * Fixed lists behavior when code fragments, tables and examples were present * Remove code tags with lang class and use instead src-:lang like org-exporter * Fixed property drawers to consider properties with hyphens like :noweb-ref: == 0.6.3 / 2012-05-22 * Minor enhancement: Correct handling of .org URIs in HTML markup routine (thanks, rayl) == 0.6.1 / 2012-04-14 * Added encoding directive to support Ruby 1.9.2 * Headlines with the COMMENT keyword, and the PROPERTIES drawer are not exported * Angle links in org-mode are embedded in anchor tags on html output * #+BEGIN/END_SRC lang code blocks are embedded in code tags with class that specifies the coding language * Fixed bug in code blocks when a colon was at the beginning * More than five dashes create an horizontal rule in html output == 0.6.0 / 2011-09-03 * Added support for a "header offset" -- turns one star into an H2, etc. (thanks, niku) * The anchor text for a link can now be an image, and will get an img tag (thanks, punchagan) * Fixed bug in tables; only the first row is a header even if others have divider lines (thanks, leathekd) * Fixed bug in the list regular expression; lists require a space after the item delimiter (thanks, punchagan) * Lots from ruediger: * subscript / superscript * definition lists * centered text * symbol replacement == 0.5.3 / 2010-02-15 * Minor enhancement: Displays inline images == 0.5.2 / 2010-01-05 * Refactored to improve layering. == 0.5.1 / 2009-12-30 * Minor enhancement: Recognize lines starting with ":" as examples. * Minor enhancement: Recognize #+BEGIN_SRC as source blocks * Minor enhancement: Add "src" and "example" classes to
blocks.
== 0.5.0 / 2009-12-30
* Parse (but not necessarily *use*) in-buffer settings. The following
in-buffer settings *are* used:
* Understand the #+TITLE: directive.
* Exporting todo keywords (option todo:t)
* Numbering headlines (option num:t)
* Skipping text before the first headline (option skip:t)
* Skipping tables (option |:nil)
* Custom todo keywords
* EXPORT_SELECT_TAGS and EXPORT_EXLUDE_TAGS for controlling parts of
the tree to export
* Rewrite "file:(blah).org" links to "http:(blah).html" links. This
makes the inter-links to other org-mode files work.
* Uses tags inside table rows that precede table separators.
* Bugfixes:
* Headings now have HTML escaped.
== 0.4.2 / 2009-12-29
* Got rid of the extraneous newline at the start of code blocks.
* Everything now shows up in code blocks, even org-mode metadata.
* Fixed bugs:
* Regressed smart double quotes with HTML escaping. Added a test
case and fixed the regression.
== 0.4.1 / 2009-12-29
* HTML is now escaped by default
* org-mode comments will show up in a code block.
== 0.4.0 / 2009-12-28
* The first thing output in HTML gets the class "title"
* HTML output is now indented
* Proper support for multi-paragraph list items.
* Fixed bugs:
* "rake spec" wouldn't work on Linux. Needed "require 'rubygems'".
== 0.3.0 / 2009-12-27
* Uses rubypants to get better typography (smart quotes, elipses, etc.).
* Fixed bugs:
* Tables and lists did not get properly closed at the end of file
* You couldn't do inline formatting inside table cells
* Characters in PRE blocks were not HTML escaped.
== 0.2.0 / 2009-12-26
* Renamed the gem to org-ruby
* Added +to_html+ for HTML output
* Now supports the following inline markup:
* bold
* italic
* code
* verbatim
* underline
* strikethrough
* Continued code cleanup and refactoring
== 0.1.0 / 2009-12-23
* Added support for block code
* Added support for list items that wrap in the org source
* Major code cleanup:
Added +OutputBuffer+ class that should make the code more maintainable.
== 0.0.2 / 2009-12-21
* Initial version. Handles tables (but not headers), headlines,
paragraphs, block quotes, strong & emphasis formatting.
ruby-org-0.8.0/README.rdoc 0000664 0000000 0000000 00000005111 12105711076 0015071 0 ustar 00root root 0000000 0000000 = org-ruby
Originally by Brian Dewey (http://github.com/bdewey/org-ruby)
{
}[http://travis-ci.org/wallyqs/org-ruby]
An {org-mode}[http://orgmode.org] parser written in Ruby. The most significant thing this library does today is convert org-mode files to HTML or Textile.
Currently, you cannot do much to customize the conversion. The supplied textile conversion is optimized for extracting
“content” from the orgfile as opposed to “metadata.”
== Installation
gem install org-ruby
== Usage
From Ruby code:
require 'org-ruby'
# Renders HTML
Orgmode::Parser.new("* Hello world!).to_html
# => "Hello world!
\n"
# Renders Textile
Orgmode::Parser.new("* Hello world!).to_textile
# => "h1. Hello world!\n"
It can also be used from the command line:
org-ruby sample.org --translate html
...will output a HTML version of sample.org.
org-ruby --translate textile sample.org
...will output a textile version of sample.org.
== Features
* Converts org-mode files to HTML or Textile
* Supports tables, block quotes, code blocks, and html blocks
* Supports bold, italic, underline, strikethrough, and code inline formatting.
* Supports hyperlinks that are in double-brackets
* Supports definition lists
* Supports footnotes
* Supports +.org+ views in Rails through Tilt.
* Code syntax highlight of code blocks using Pygments.rb or Coderay when available
== License
(The MIT License)
Copyright (c) 2009 Brian Dewey
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ruby-org-0.8.0/Rakefile 0000664 0000000 0000000 00000000425 12105711076 0014733 0 ustar 00root root 0000000 0000000 require 'rspec/core'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec) do |spec|
spec.pattern = FileList['spec/**/*_spec.rb']
spec.rspec_opts = ["--format", "documentation", "--colour"]
end
Dir['tasks/*'].each {|task| import task }
task :default => 'test'
ruby-org-0.8.0/announcement.txt 0000664 0000000 0000000 00000001201 12105711076 0016512 0 ustar 00root root 0000000 0000000 org-ruby version 0.8.0
by Brian Dewey
http://github.com/bdewey/org-ruby
== DESCRIPTION
This gem contains Ruby routines for parsing org-mode files.The most
significant thing this library does today is convert org-mode files to
HTML or textile.
== CHANGES
* A lot of refactoring work and bugfixes contributed by vonavi (many thanks!)
* Raw HTML is supported with #+html
* Code indentation for code blocks is fixed now
* Support for definition lists is improved
* Bugfix for when including headlines in center and quote blocks.
* Indentation of HTML output improved
* Improvements to entities support for Textile and HTML outputs
ruby-org-0.8.0/bench/ 0000775 0000000 0000000 00000000000 12105711076 0014344 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/bench/Gemfile 0000664 0000000 0000000 00000000140 12105711076 0015632 0 ustar 00root root 0000000 0000000 source :rubygems
# Bench with the current version in development
gem 'org-ruby', :path => '..'
ruby-org-0.8.0/bench/Gemfile_6_0 0000664 0000000 0000000 00000000052 12105711076 0016300 0 ustar 00root root 0000000 0000000 source :rubygems
gem 'org-ruby', '0.6.0'
ruby-org-0.8.0/bench/Gemfile_6_1 0000664 0000000 0000000 00000000052 12105711076 0016301 0 ustar 00root root 0000000 0000000 source :rubygems
gem 'org-ruby', '0.6.1'
ruby-org-0.8.0/bench/Gemfile_6_2 0000664 0000000 0000000 00000000052 12105711076 0016302 0 ustar 00root root 0000000 0000000 source :rubygems
gem 'org-ruby', '0.6.2'
ruby-org-0.8.0/bench/Gemfile_6_3 0000664 0000000 0000000 00000000052 12105711076 0016303 0 ustar 00root root 0000000 0000000 source :rubygems
gem 'org-ruby', '0.6.3'
ruby-org-0.8.0/bench/Gemfile_redcarpet 0000664 0000000 0000000 00000000042 12105711076 0017664 0 ustar 00root root 0000000 0000000 source :rubygems
gem 'redcarpet'
ruby-org-0.8.0/bench/bench.org 0000664 0000000 0000000 00000024140 12105711076 0016135 0 ustar 00root root 0000000 0000000 * OrgRuby benchmarks
** How to run the benchmarks (or trying out org-babel)
Within this folder there is a =parsing_test.rb= script which can be used
to profile a quick benchmark of the current performance of the org-ruby library.
What follows are the results of my benchmark by using the built-in support
for org-babel included in Emacs 24. (press C-c C-c when over the block to update the benchmark)
** Platform: 1.8.7
For some reason performance is a bit better when using Ruby 1.8.7
than when using 1.9.2.
*** OrgRuby 0.6.0
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.8.7 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_0" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_0" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.0 with Ruby 1.8.7
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 1.820000 0.040000 1.860000 ( 1.894356)
: ------------------------------------------ total: 1.860000sec
:
: user system total real
: html conversion 1.840000 0.010000 1.850000 ( 1.878953)
*** OrgRuby 0.6.2
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.8.7 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_2" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_2" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.2 with Ruby 1.8.7
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 2.060000 0.030000 2.090000 ( 2.123677)
: ------------------------------------------ total: 2.090000sec
:
: user system total real
: html conversion 2.080000 0.030000 2.110000 ( 2.135976)
*** OrgRuby 0.6.3
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.8.7 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_3" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_3" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.3 with Ruby 1.8.7
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 2.060000 0.040000 2.100000 ( 2.126579)
: ------------------------------------------ total: 2.100000sec
:
: user system total real
: html conversion 2.090000 0.030000 2.120000 ( 2.139272)
*** DEV
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.8.7 > /dev/null
rvm info | grep full_version
bundle install > /dev/null
bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.3 with Ruby 1.8.7
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 2.050000 0.030000 2.080000 ( 2.147836)
: ------------------------------------------ total: 2.080000sec
:
: user system total real
: html conversion 2.050000 0.030000 2.080000 ( 2.102787)
** Platform: 1.9.2
Remember that 1.9.2 is sensible to encoding issues. (e.g. あいうえお)
*** OrgRuby 0.6.0
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
export LANG=en_US.UTF-8
rvm use 1.9.2 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_0" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_0" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.0 with Ruby 1.9.2
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 3.250000 0.020000 3.270000 ( 3.313767)
: ------------------------------------------ total: 3.270000sec
:
: user system total real
: html conversion 3.220000 0.020000 3.240000 ( 3.307011)
*** OrgRuby 0.6.2
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
export LANG=en_US.UTF-8
rvm use 1.9.2 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_2" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_2" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.2 with Ruby 1.9.2
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 3.440000 0.030000 3.470000 ( 3.529776)
: ------------------------------------------ total: 3.470000sec
:
: user system total real
: html conversion 3.440000 0.030000 3.470000 ( 3.519090)
*** OrgRuby 0.6.3
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
export LANG=en_US.UTF-8
rvm use 1.9.2 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_6_3" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_6_3" bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.3 with Ruby 1.9.2
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 3.430000 0.030000 3.460000 ( 3.526293)
: ------------------------------------------ total: 3.460000sec
:
: user system total real
: html conversion 3.440000 0.030000 3.470000 ( 3.525800)
*** DEV
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
export LANG=en_US.UTF-8
rvm use 1.9.2 > /dev/null
rvm info | grep full_version
bundle install > /dev/null
bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.3 with Ruby 1.9.2
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 3.380000 0.020000 3.400000 ( 3.469689)
: ------------------------------------------ total: 3.400000sec
:
: user system total real
: html conversion 3.380000 0.030000 3.410000 ( 3.441502)
** Platform: 1.9.3
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
export LANG=en_US.UTF-8
rvm use 1.9.3 > /dev/null
rvm info | grep full_version
bundle install > /dev/null
bundle exec ruby parsing_test.rb
#+END_SRC
#+RESULTS:
: full_version: "ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]"
: Running benchmark with OrgRuby version 0.6.3 with Ruby 1.9.3
: Parsing 30 times
: Rehearsal ---------------------------------------------------
: html conversion 3.810000 0.020000 3.830000 ( 3.960345)
: ------------------------------------------ total: 3.830000sec
:
: user system total real
: html conversion 3.790000 0.020000 3.810000 ( 3.848413)
** Other benchmarks
*** Similar benchmark using other markup libraries
**** Markdown using Redcarpet in Ruby 1.8.7
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.8.7 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle exec ruby parsing_redcarpet_test.rb
#+END_SRC
#+RESULTS:
#+begin_example
full_version: "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.2.0]"
Running benchmark with RedCarpet with Ruby 1.8.7 (n=30)
Parsing 30 times
Rehearsal ------------------------------------------------------------------
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.007885)
--------------------------------------------------------- total: 0.010000sec
user system total real
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.007482)
0.010000 0.000000 0.010000 ( 0.007482)
#+end_example
**** Markdown using Redcarpet in Ruby 1.9.2
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.9.2 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle exec ruby parsing_redcarpet_test.rb
#+END_SRC
#+RESULTS:
#+begin_example
full_version: "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.2.0]"
Running benchmark with RedCarpet with Ruby 1.9.2 (n=30)
Parsing 30 times
Rehearsal ------------------------------------------------------------------
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.007588)
--------------------------------------------------------- total: 0.010000sec
user system total real
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.007063)
0.010000 0.000000 0.010000 ( 0.007063)
#+end_example
**** Markdown using Redcarpet in Ruby 1.9.3
#+BEGIN_SRC sh :results verbatim
source ~/.bashrc
rvm use 1.9.3 > /dev/null
rvm info | grep full_version
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle install > /dev/null
BUNDLE_GEMFILE="Gemfile_redcarpet" bundle exec ruby parsing_redcarpet_test.rb
#+END_SRC
#+RESULTS:
#+begin_example
full_version: "ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]"
Running benchmark with RedCarpet with Ruby 1.9.3 (n=30)
Parsing 30 times
Rehearsal ------------------------------------------------------------------
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.007438)
--------------------------------------------------------- total: 0.010000sec
user system total real
html conversion with Redcarpet 0.010000 0.000000 0.010000 ( 0.006909)
0.010000 0.000000 0.010000 ( 0.006909)
#+end_example
*** TODO Encoding benchmarks
**** Not setting default Encoding
**** Setting Encoding::UTF_8 as default
**** Setting Encoding::ASCII_8BIT as default
ruby-org-0.8.0/bench/parsing_redcarpet_test.rb 0000664 0000000 0000000 00000000700 12105711076 0021421 0 ustar 00root root 0000000 0000000 require 'redcarpet'
require 'benchmark'
def run_benchmark(n=30)
org_content = File.open('bench.org').read
puts "Parsing #{n} times"
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
Benchmark.bmbm do |x|
x.report('html conversion with Redcarpet') do
n.times do
markdown.render(org_content)
end
end
end
end
puts "Running benchmark with RedCarpet with Ruby #{RUBY_VERSION} (n=30)"
run_benchmark
ruby-org-0.8.0/bench/parsing_test.rb 0000664 0000000 0000000 00000001574 12105711076 0017402 0 ustar 00root root 0000000 0000000 require 'org-ruby'
require 'benchmark'
def run_html_output_benchmark(n=30)
org_content = File.open('bench.org').read
puts "Parsing #{n} times"
Benchmark.bmbm do |x|
x.report('html conversion') do
n.times do
Orgmode::Parser.new(org_content).to_html
end
end
end
end
def run_textile_output_benchmark(n=30)
org_content = File.open('bench.org').read
puts "Parsing #{n} times"
x.report('textile conversion') do
n.times do
Orgmode::Parser.new(content).to_textile
end
end
end
def run_parsing_file_benchmark(n=30)
puts "Parsing #{n} times"
x.report('textile conversion') do
n.times do
Orgmode::Parser.load('bench.org')
end
end
end
puts "Running benchmark using OrgRuby version #{OrgRuby::VERSION} with Ruby #{RUBY_VERSION}"
run_html_output_benchmark
# run_textile_output_benchmark
# run_parsing_file_benchmark
ruby-org-0.8.0/bin/ 0000775 0000000 0000000 00000000000 12105711076 0014035 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/bin/org-ruby 0000775 0000000 0000000 00000002063 12105711076 0015532 0 ustar 00root root 0000000 0000000 #!/usr/bin/env ruby
require 'org-ruby'
require 'optparse'
options = {}
options_parser = OptionParser.new do |opts|
options[:help] = false
options[:format] = :html
opts.banner = "Usage: org-ruby [options]"
opts.on("-h", "--help", "Show this message") do |v|
options[:help] = true
end
opts.on("-d", "--debug", "Run with $DEBUG true") do |v|
options[:debug] = true
end
opts.on("-t", "--translate FORMAT", [:html, :textile],
"Translate the ORG file to the specified format.") do |v|
options[:format] = v
end
opts.on("-v", "--version", "Print version") do |v|
options[:version] = true
end
end
begin
options_parser.parse!
if options[:version]
puts OrgRuby::VERSION
exit
end
if (ARGV.length == 0) then
puts options_parser
else
data = IO.read(ARGV[0])
p = Orgmode::Parser.new(data)
$DEBUG = true if options[:debug]
puts p.to_html if options[:format] == :html
puts p.to_textile if options[:format] == :textile
end
rescue OptionParser::ParseError
puts options_parser
end
ruby-org-0.8.0/lib/ 0000775 0000000 0000000 00000000000 12105711076 0014033 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/lib/org-ruby.rb 0000664 0000000 0000000 00000002460 12105711076 0016130 0 ustar 00root root 0000000 0000000 $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
# internal requires
require 'org-ruby/parser'
require 'org-ruby/regexp_helper'
require 'org-ruby/line'
require 'org-ruby/headline'
require 'org-ruby/output_buffer'
# HTML exporter
require 'org-ruby/html_output_buffer'
require 'org-ruby/html_symbol_replace'
# Textile exporter
require 'org-ruby/textile_output_buffer'
require 'org-ruby/textile_symbol_replace'
# Tilt support
require 'org-ruby/tilt'
module OrgRuby
# :stopdoc:
VERSION = '0.8.0'
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
# :startdoc:
# Returns the version string for the library.
#
def self.version
VERSION
end
# Utility method used to require all files ending in .rb that lie in the
# directory below this file that has the same name as the filename passed
# in. Optionally, a specific _directory_ name can be passed in such that
# the _filename_ does not have to be equivalent to the directory.
#
def self.require_all_libs_relative_to( fname, dir = nil )
dir ||= ::File.basename(fname, '.*')
search_me = ::File.expand_path(
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
Dir.glob(search_me).sort.each {|rb| require rb}
end
end
ruby-org-0.8.0/lib/org-ruby/ 0000775 0000000 0000000 00000000000 12105711076 0015601 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/lib/org-ruby/headline.rb 0000664 0000000 0000000 00000006006 12105711076 0017701 0 ustar 00root root 0000000 0000000 module Orgmode
# Represents a headline in an orgmode file.
class Headline < Line
# This is the "level" of the headline
attr_reader :level
# This is the headline text -- the part of the headline minus the leading
# asterisks, the keywords, and the tags.
attr_reader :headline_text
# This contains the lines that "belong" to the headline.
attr_reader :body_lines
# These are the headline tags
attr_reader :tags
# Optional keyword found at the beginning of the headline.
attr_reader :keyword
# Valid states for partial export.
# exclude:: The entire subtree from this heading should be excluded.
# headline_only:: The headline should be exported, but not the body.
# all:: Everything should be exported, headline/body/children.
ValidExportStates = [:exclude, :headline_only, :all]
# The export state of this headline. See +ValidExportStates+.
attr_accessor :export_state
# This is the regex that matches a line
LineRegexp = /^\*+\s+/
# This matches the tags on a headline
TagsRegexp = /\s*:[\w:]*:\s*$/
# Special keywords allowed at the start of a line.
Keywords = %w[TODO DONE]
KeywordsRegexp = Regexp.new("^(#{Keywords.join('|')})\$")
# This matches a headline marked as COMMENT
CommentHeadlineRegexp = /^COMMENT\s+/
def initialize(line, parser = nil, offset=0)
super(line, parser)
@body_lines = []
@tags = []
@export_state = :exclude
if (@line =~ LineRegexp) then
@level = $&.strip.length + offset
@headline_text = $'.strip
if (@headline_text =~ TagsRegexp) then
@tags = $&.split(/:/) # split tag text on semicolon
@tags.delete_at(0) # the first item will be empty; discard
@headline_text.gsub!(TagsRegexp, "") # Removes the tags from the headline
end
@keyword = nil
parse_keywords
else
raise "'#{line}' is not a valid headline"
end
end
# Override Line.output_text. For a heading, @headline_text
# is what we should output.
def output_text
return @headline_text
end
# Determines if a line is an orgmode "headline":
# A headline begins with one or more asterisks.
def self.headline?(line)
line =~ LineRegexp
end
# Determines if a headline has the COMMENT keyword.
def comment_headline?
@headline_text =~ CommentHeadlineRegexp
end
# Overrides Line.paragraph_type.
def paragraph_type
:"heading#{@level}"
end
######################################################################
private
def parse_keywords
re = @parser.custom_keyword_regexp if @parser
re ||= KeywordsRegexp
words = @headline_text.split
if words.length > 0 && words[0] =~ re then
@keyword = words[0]
@headline_text.sub!(Regexp.new("^#{@keyword}\s*"), "")
end
end
end # class Headline
end # class Orgmode
ruby-org-0.8.0/lib/org-ruby/html_output_buffer.rb 0000664 0000000 0000000 00000025660 12105711076 0022054 0 ustar 00root root 0000000 0000000 begin
require 'pygments'
rescue LoadError
# Pygments is not supported so we try instead with CodeRay
begin
require 'coderay'
rescue LoadError
# No code syntax highlighting
end
end
module Orgmode
class HtmlOutputBuffer < OutputBuffer
HtmlBlockTag = {
:paragraph => "p",
:ordered_list => "ol",
:unordered_list => "ul",
:list_item => "li",
:definition_list => "dl",
:definition_term => "dt",
:definition_descr => "dd",
:table => "table",
:table_row => "tr",
:quote => "blockquote",
:example => "pre",
:src => "pre",
:inline_example => "pre",
:center => "div",
:heading1 => "h1",
:heading2 => "h2",
:heading3 => "h3",
:heading4 => "h4",
:heading5 => "h5",
:heading6 => "h6"
}
attr_reader :options
def initialize(output, opts = {})
super(output)
if opts[:decorate_title] then
@title_decoration = " class=\"title\""
else
@title_decoration = ""
end
@buffer_tag = "HTML"
@options = opts
@new_paragraph = :start
@footnotes = {}
@unclosed_tags = []
@logger.debug "HTML export options: #{@options.inspect}"
end
# Output buffer is entering a new mode. Use this opportunity to
# write out one of the block tags in the HtmlBlockTag constant to
# put this information in the HTML stream.
def push_mode(mode, indent)
super(mode)
@list_indent_stack.push(indent)
if HtmlBlockTag[mode]
unless ((mode_is_table?(mode) and skip_tables?) or
(mode == :src and defined? Pygments))
css_class = case
when (mode == :src and @block_lang.empty?)
" class=\"src\""
when (mode == :src and not @block_lang.empty?)
" class=\"src src-#{@block_lang}\""
when (mode == :example || mode == :inline_example)
" class=\"example\""
when mode == :center
" style=\"text-align: center\""
else
@title_decoration
end
add_paragraph unless @new_paragraph == :start
@new_paragraph = true
@logger.debug "#{mode}: <#{HtmlBlockTag[mode]}#{css_class}>"
@output << "<#{HtmlBlockTag[mode]}#{css_class}>"
# Entering a new mode obliterates the title decoration
@title_decoration = ""
end
end
end
# We are leaving a mode. Close any tags that were opened when
# entering this mode.
def pop_mode(mode = nil)
m = super(mode)
if HtmlBlockTag[m]
unless ((mode_is_table?(m) and skip_tables?) or
(m == :src and defined? Pygments))
add_paragraph if @new_paragraph
@new_paragraph = true
@logger.debug "#{HtmlBlockTag[m]}>"
@output << "#{HtmlBlockTag[m]}>"
end
end
@list_indent_stack.pop
end
def flush!
return false if @buffer.empty?
case
when preserve_whitespace?
strip_code_block! if mode_is_code? current_mode
# NOTE: CodeRay and Pygments already escape the html once, so
# no need to escape_string!(@buffer)
case
when (current_mode == :src and defined? Pygments)
lang = normalize_lang @block_lang
@output << "\n" unless @new_paragraph == :start
begin
@buffer = Pygments.highlight(@buffer, :lexer => lang)
rescue
# Not supported lexer from Pygments, we fallback on using the text lexer
@buffer = Pygments.highlight(@buffer, :lexer => 'text')
end
when (current_mode == :src and defined? CodeRay)
lang = normalize_lang @block_lang
# CodeRay might throw a warning when unsupported lang is set,
# then fallback to using the text lexer
silence_warnings do
begin
@buffer = CodeRay.scan(@buffer, lang).html(:wrap => nil, :css => :style)
rescue ArgumentError
@buffer = CodeRay.scan(@buffer, 'text').html(:wrap => nil, :css => :style)
end
end
when (current_mode == :html or current_mode == :raw_text)
@buffer.gsub!(/\A\n/, "") if @new_paragraph == :start
@new_paragraph = true
else
escape_string! @buffer
end
# Whitespace is significant in :code mode. Always output the
# buffer and do not do any additional translation.
@logger.debug "FLUSH CODE ==========> #{@buffer.inspect}"
@output << @buffer
when (mode_is_table? current_mode and skip_tables?)
@logger.debug "SKIP ==========> #{current_mode}"
else
@buffer.lstrip!
@new_paragraph = nil
@logger.debug "FLUSH ==========> #{current_mode}"
case current_mode
when :definition_term
d = @buffer.split(/\A(.*[ \t]+|)::(|[ \t]+.*?)$/, 4)
d[1] = d[1].strip
unless d[1].empty?
@output << inline_formatting(d[1])
else
@output << "???"
end
indent = @list_indent_stack.last
pop_mode
@new_paragraph = :start
push_mode(:definition_descr, indent)
@output << inline_formatting(d[2].strip + d[3])
@new_paragraph = nil
when :horizontal_rule
add_paragraph unless @new_paragraph == :start
@new_paragraph = true
@output << "
"
else
@output << inline_formatting(@buffer)
end
end
@buffer = ""
end
def add_line_attributes headline
if @options[:export_heading_number] then
level = headline.level
heading_number = get_next_headline_number(level)
@output << "#{heading_number} "
end
if @options[:export_todo] and headline.keyword then
keyword = headline.keyword
@output << "#{keyword} "
end
end
def output_footnotes!
return false unless @options[:export_footnotes] and not @footnotes.empty?
@output << "\n\nFootnotes:
\n\n"
@footnotes.each do |name, defi|
@output << "#{name}" \
<< inline_formatting(defi) \
<< "
\n"
end
@output << "\n"
return true
end
# Test if we're in an output mode in which whitespace is significant.
def preserve_whitespace?
super or current_mode == :html
end
######################################################################
private
def skip_tables?
@options[:skip_tables]
end
def mode_is_table?(mode)
(mode == :table or mode == :table_row or
mode == :table_separator or mode == :table_header)
end
# Escapes any HTML content in the output accumulation buffer @buffer.
def escape_string! str
str.gsub!(/&/, "&")
# Escapes the left and right angular brackets but construction
# @ which is formatted to
str.gsub! /<([^<>\n]*)/ do |match|
if $`[-1..-1] == "@" and $'[0..0] == ">" then $&
else "<#{$1}"
end
end
str.gsub! /([^<>\n]*)>/ do |match|
if $`[-2..-1] == "@<" then $&
else "#{$1}>"
end
end
str.gsub!(/@(<[^<>\n]*>)/, "\\1")
end
def buffer_indentation
indent = " " * @list_indent_stack.length
@buffer << indent
end
def add_paragraph
indent = " " * (@list_indent_stack.length - 1)
@output << "\n" << indent
end
Tags = {
"*" => { :open => "b", :close => "b" },
"/" => { :open => "i", :close => "i" },
"_" => { :open => "span style=\"text-decoration:underline;\"",
:close => "span" },
"=" => { :open => "code", :close => "code" },
"~" => { :open => "code", :close => "code" },
"+" => { :open => "del", :close => "del" }
}
# Applies inline formatting rules to a string.
def inline_formatting(str)
@re_help.rewrite_emphasis str do |marker, s|
"@<#{Tags[marker][:open]}>#{s}@#{Tags[marker][:close]}>"
end
if @options[:use_sub_superscripts] then
@re_help.rewrite_subp str do |type, text|
if type == "_" then
"@#{text}@"
elsif type == "^" then
"@#{text}@"
end
end
end
@re_help.rewrite_links str do |link, defi|
[link, defi].compact.each do |text|
# We don't support search links right now. Get rid of it.
text.sub!(/\A(file:[^\s]+)::[^\s]*?\Z/, "\\1")
text.sub!(/\A(file:[^\s]+)\.org\Z/i, "\\1.html")
text.sub!(/\Afile:(?=[^\s]+\Z)/, "")
end
# We don't add a description for images in links, because its
# empty value forces the image to be inlined.
defi ||= link unless link =~ @re_help.org_image_file_regexp
if defi =~ @re_help.org_image_file_regexp
defi = "@
"
end
if defi
"@#{defi}@"
else
"@
"
end
end
if @output_type == :table_row
str.gsub!(/^\|\s*/, "@")
str.gsub!(/\s*\|$/, "@ ")
str.gsub!(/\s*\|\s*/, "@@")
end
if @output_type == :table_header
str.gsub!(/^\|\s*/, "@ ")
str.gsub!(/\s*\|$/, "@ ")
str.gsub!(/\s*\|\s*/, "@ @")
end
if @options[:export_footnotes] then
@re_help.rewrite_footnote str do |name, defi|
# TODO escape name for url?
@footnotes[name] = defi if defi
"@@#{name}@@"
end
end
escape_string! str
Orgmode.special_symbols_to_html str
str = @re_help.restore_code_snippets str
end
def normalize_lang(lang)
case lang
when 'emacs-lisp', 'common-lisp', 'lisp'
'scheme'
when ''
'text'
else
lang
end
end
# Helper method taken from Rails
# https://github.com/rails/rails/blob/c2c8ef57d6f00d1c22743dc43746f95704d67a95/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10
def silence_warnings
warn_level = $VERBOSE
$VERBOSE = nil
yield
ensure
$VERBOSE = warn_level
end
def strip_code_block!
strip_regexp = Regexp.new("^" + " " * @code_block_indent)
@buffer.gsub!(strip_regexp, "")
@code_block_indent = nil
end
end # class HtmlOutputBuffer
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/html_symbol_replace.rb 0000664 0000000 0000000 00000021607 12105711076 0022160 0 ustar 00root root 0000000 0000000 # Autogenerated by util/gen-special-replace.el
module Orgmode
HtmlEntities = {
"Agrave" => "À",
"agrave" => "à",
"Aacute" => "Á",
"aacute" => "á",
"Acirc" => "Â",
"acirc" => "â",
"Atilde" => "Ã",
"atilde" => "ã",
"Auml" => "Ä",
"auml" => "ä",
"Aring" => "Å",
"AA" => "Å",
"aring" => "å",
"AElig" => "Æ",
"aelig" => "æ",
"Ccedil" => "Ç",
"ccedil" => "ç",
"Egrave" => "È",
"egrave" => "è",
"Eacute" => "É",
"eacute" => "é",
"Ecirc" => "Ê",
"ecirc" => "ê",
"Euml" => "Ë",
"euml" => "ë",
"Igrave" => "Ì",
"igrave" => "ì",
"Iacute" => "Í",
"iacute" => "í",
"Icirc" => "Î",
"icirc" => "î",
"Iuml" => "Ï",
"iuml" => "ï",
"Ntilde" => "Ñ",
"ntilde" => "ñ",
"Ograve" => "Ò",
"ograve" => "ò",
"Oacute" => "Ó",
"oacute" => "ó",
"Ocirc" => "Ô",
"ocirc" => "ô",
"Otilde" => "Õ",
"otilde" => "õ",
"Ouml" => "Ö",
"ouml" => "ö",
"Oslash" => "Ø",
"oslash" => "ø",
"OElig" => "Œ",
"oelig" => "œ",
"Scaron" => "Š",
"scaron" => "š",
"szlig" => "ß",
"Ugrave" => "Ù",
"ugrave" => "ù",
"Uacute" => "Ú",
"uacute" => "ú",
"Ucirc" => "Û",
"ucirc" => "û",
"Uuml" => "Ü",
"uuml" => "ü",
"Yacute" => "Ý",
"yacute" => "ý",
"Yuml" => "Ÿ",
"yuml" => "ÿ",
"fnof" => "ƒ",
"real" => "ℜ",
"image" => "ℑ",
"weierp" => "℘",
"Alpha" => "Α",
"alpha" => "α",
"Beta" => "Β",
"beta" => "β",
"Gamma" => "Γ",
"gamma" => "γ",
"Delta" => "Δ",
"delta" => "δ",
"Epsilon" => "Ε",
"epsilon" => "ε",
"varepsilon" => "ε",
"Zeta" => "Ζ",
"zeta" => "ζ",
"Eta" => "Η",
"eta" => "η",
"Theta" => "Θ",
"theta" => "θ",
"thetasym" => "ϑ",
"vartheta" => "ϑ",
"Iota" => "Ι",
"iota" => "ι",
"Kappa" => "Κ",
"kappa" => "κ",
"Lambda" => "Λ",
"lambda" => "λ",
"Mu" => "Μ",
"mu" => "μ",
"nu" => "ν",
"Nu" => "Ν",
"Xi" => "Ξ",
"xi" => "ξ",
"Omicron" => "Ο",
"omicron" => "ο",
"Pi" => "Π",
"pi" => "π",
"Rho" => "Ρ",
"rho" => "ρ",
"Sigma" => "Σ",
"sigma" => "σ",
"sigmaf" => "ς",
"varsigma" => "ς",
"Tau" => "Τ",
"Upsilon" => "Υ",
"upsih" => "ϒ",
"upsilon" => "υ",
"Phi" => "Φ",
"phi" => "φ",
"Chi" => "Χ",
"chi" => "χ",
"acutex" => "´x",
"Psi" => "Ψ",
"psi" => "ψ",
"tau" => "τ",
"Omega" => "Ω",
"omega" => "ω",
"piv" => "ϖ",
"partial" => "∂",
"alefsym" => "ℵ",
"ETH" => "Ð",
"eth" => "ð",
"THORN" => "Þ",
"thorn" => "þ",
"dots" => "…",
"hellip" => "…",
"middot" => "·",
"iexcl" => "¡",
"iquest" => "¿",
"shy" => "",
"ndash" => "–",
"mdash" => "—",
"quot" => """,
"acute" => "´",
"ldquo" => "“",
"rdquo" => "”",
"bdquo" => "„",
"lsquo" => "‘",
"rsquo" => "’",
"sbquo" => "‚",
"laquo" => "«",
"raquo" => "»",
"lsaquo" => "‹",
"rsaquo" => "›",
"circ" => "ˆ",
"vert" => "|",
"brvbar" => "¦",
"sect" => "§",
"amp" => "&",
"lt" => "<",
"gt" => ">",
"tilde" => "˜",
"slash" => "/",
"plus" => "+",
"under" => "_",
"equal" => "=",
"asciicirc" => "^",
"dagger" => "†",
"Dagger" => "‡",
"nbsp" => " ",
"ensp" => " ",
"emsp" => " ",
"thinsp" => " ",
"curren" => "¤",
"cent" => "¢",
"pound" => "£",
"yen" => "¥",
"euro" => "€",
"EUR" => "€",
"EURdig" => "€",
"EURhv" => "€",
"EURcr" => "€",
"EURtm" => "€",
"copy" => "©",
"reg" => "®",
"trade" => "™",
"minus" => "−",
"pm" => "±",
"plusmn" => "±",
"times" => "×",
"frasl" => "⁄",
"div" => "÷",
"frac12" => "½",
"frac14" => "¼",
"frac34" => "¾",
"permil" => "‰",
"sup1" => "¹",
"sup2" => "²",
"sup3" => "³",
"radic" => "√",
"sum" => "∑",
"prod" => "∏",
"micro" => "µ",
"macr" => "¯",
"deg" => "°",
"prime" => "′",
"Prime" => "″",
"infin" => "∞",
"infty" => "∞",
"prop" => "∝",
"proptp" => "∝",
"not" => "¬",
"neg" => "¬",
"land" => "∧",
"wedge" => "∧",
"lor" => "∨",
"vee" => "∨",
"cap" => "∩",
"cup" => "∪",
"int" => "∫",
"there4" => "∴",
"sim" => "∼",
"cong" => "≅",
"simeq" => "≅",
"asymp" => "≈",
"approx" => "≈",
"ne" => "≠",
"neq" => "≠",
"equiv" => "≡",
"le" => "≤",
"ge" => "≥",
"sub" => "⊂",
"subset" => "⊂",
"sup" => "⊃",
"supset" => "⊃",
"nsub" => "⊄",
"sube" => "⊆",
"nsup" => "⊅",
"supe" => "⊇",
"forall" => "∀",
"exist" => "∃",
"exists" => "∃",
"empty" => "∅",
"emptyset" => "∅",
"isin" => "∈",
"in" => "∈",
"notin" => "∉",
"ni" => "∋",
"nabla" => "∇",
"ang" => "∠",
"angle" => "∠",
"perp" => "⊥",
"sdot" => "⋅",
"cdot" => "⋅",
"lceil" => "⌈",
"rceil" => "⌉",
"lfloor" => "⌊",
"rfloor" => "⌋",
"lang" => "〈",
"rang" => "〉",
"larr" => "←",
"leftarrow" => "←",
"gets" => "←",
"lArr" => "⇐",
"Leftarrow" => "⇐",
"uarr" => "↑",
"uparrow" => "↑",
"uArr" => "⇑",
"Uparrow" => "⇑",
"rarr" => "→",
"to" => "→",
"rightarrow" => "→",
"rArr" => "⇒",
"Rightarrow" => "⇒",
"darr" => "↓",
"downarrow" => "↓",
"dArr" => "⇓",
"Downarrow" => "⇓",
"harr" => "↔",
"leftrightarrow" => "↔",
"hArr" => "⇔",
"Leftrightarrow" => "⇔",
"crarr" => "↵",
"hookleftarrow" => "↵",
"arccos" => "arccos",
"arcsin" => "arcsin",
"arctan" => "arctan",
"arg" => "arg",
"cos" => "cos",
"cosh" => "cosh",
"cot" => "cot",
"coth" => "coth",
"csc" => "csc",
"deg" => "°",
"det" => "det",
"dim" => "dim",
"exp" => "exp",
"gcd" => "gcd",
"hom" => "hom",
"inf" => "inf",
"ker" => "ker",
"lg" => "lg",
"lim" => "lim",
"liminf" => "liminf",
"limsup" => "limsup",
"ln" => "ln",
"log" => "log",
"max" => "max",
"min" => "min",
"Pr" => "Pr",
"sec" => "sec",
"sin" => "sin",
"sinh" => "sinh",
"sup" => "⊃",
"tan" => "tan",
"tanh" => "tanh",
"bull" => "•",
"bullet" => "•",
"star" => "*",
"lowast" => "∗",
"ast" => "∗",
"odot" => "o",
"oplus" => "⊕",
"otimes" => "⊗",
"checkmark" => "✓",
"para" => "¶",
"ordf" => "ª",
"ordm" => "º",
"cedil" => "¸",
"oline" => "‾",
"uml" => "¨",
"zwnj" => "",
"zwj" => "",
"lrm" => "",
"rlm" => "",
"smile" => "☺",
"smiley" => "☺",
"blacksmile" => "☻",
"sad" => "☹",
"clubs" => "♣",
"clubsuit" => "♣",
"spades" => "♠",
"spadesuit" => "♠",
"hearts" => "♥",
"heartsuit" => "♥",
"diams" => "♦",
"diamondsuit" => "♦",
"Diamond" => "⋄",
"loz" => "◊"
}
@org_entities_regexp = /\\(there4|sup[123]|frac[13][24]|[a-zA-Z]+)($|\{\}|[^a-zA-Z])/
def Orgmode.special_symbols_to_html str
str.gsub! @org_entities_regexp do |match|
if HtmlEntities[$1]
if $2 == "{}" then "#{HtmlEntities[$1]}"
else "#{HtmlEntities[$1]}#{$2}"
end
else
$&
end
end
end
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/line.rb 0000664 0000000 0000000 00000021065 12105711076 0017061 0 ustar 00root root 0000000 0000000 module Orgmode
# Represents a single line of an orgmode file.
class Line
# This is the line itself.
attr_reader :line
# The indent level of this line. this is important to properly translate
# nested lists from orgmode to textile.
# TODO 2009-12-20 bdewey: Handle tabs
attr_reader :indent
# Backpointer to the parser that owns this line.
attr_reader :parser
# Paragraph type determined for the line.
attr_reader :paragraph_type
# Major modes associate paragraphs with a table, list and so on.
attr_reader :major_mode
# A line can have its type assigned instead of inferred from its
# content. For example, something that parses as a "table" on its
# own ("| one | two|\n") may just be a paragraph if it's inside
# #+BEGIN_EXAMPLE. Set this property on the line to assign its
# type. This will then affect the value of +paragraph_type+.
attr_accessor :assigned_paragraph_type
def initialize(line, parser = nil)
@parser = parser
@line = line
@indent = 0
@line =~ /\s*/
determine_paragraph_type
determine_major_mode
@assigned_paragraph_type = nil
@indent = $&.length unless blank?
end
def to_s
return @line
end
# Tests if a line is a comment.
def comment?
return @assigned_paragraph_type == :comment if @assigned_paragraph_type
return block_type.casecmp("COMMENT") if begin_block? or end_block?
return @line =~ /^#/
end
PropertyDrawerRegexp = /^\s*:(PROPERTIES|END):/i
def property_drawer_begin_block?
@line =~ PropertyDrawerRegexp && $1 =~ /PROPERTIES/
end
def property_drawer_end_block?
@line =~ PropertyDrawerRegexp && $1 =~ /END/
end
def property_drawer?
check_assignment_or_regexp(:property_drawer, PropertyDrawerRegexp)
end
PropertyDrawerItemRegexp = /^\s*:([0-9A-Za-z_\-]+):\s*(.*)$/i
def property_drawer_item?
@line =~ PropertyDrawerItemRegexp
end
# Tests if a line contains metadata instead of actual content.
def metadata?
check_assignment_or_regexp(:metadata, /^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/)
end
def nonprinting?
comment? || metadata? || begin_block? || end_block?
end
def blank?
check_assignment_or_regexp(:blank, /^\s*$/)
end
def plain_list?
ordered_list? or unordered_list? or definition_list?
end
UnorderedListRegexp = /^\s*(-|\+|\s+[*])\s+/
def unordered_list?
check_assignment_or_regexp(:unordered_list, UnorderedListRegexp)
end
def strip_unordered_list_tag
@line.sub(UnorderedListRegexp, "")
end
DefinitionListRegexp = /^\s*(-|\+|\s+[*])\s+(.*\s+|)::($|\s+)/
def definition_list?
check_assignment_or_regexp(:definition_list, DefinitionListRegexp)
end
OrderedListRegexp = /^\s*\d+(\.|\))\s+/
def ordered_list?
check_assignment_or_regexp(:ordered_list, OrderedListRegexp)
end
def strip_ordered_list_tag
@line.sub(OrderedListRegexp, "")
end
HorizontalRuleRegexp = /^\s*-{5,}\s*$/
def horizontal_rule?
check_assignment_or_regexp(:horizontal_rule, HorizontalRuleRegexp)
end
# Extracts meaningful text and excludes org-mode markup,
# like identifiers for lists or headings.
def output_text
return strip_ordered_list_tag if ordered_list?
return strip_unordered_list_tag if unordered_list?
return @line.sub(InlineExampleRegexp, "") if inline_example?
return strip_raw_text_tag if raw_text?
return line
end
def plain_text?
not metadata? and not blank? and not plain_list?
end
def table_row?
# for an org-mode table, the first non-whitespace character is a
# | (pipe).
check_assignment_or_regexp(:table_row, /^\s*\|/)
end
def table_separator?
# an org-mode table separator has the first non-whitespace
# character as a | (pipe), then consists of nothing else other
# than pipes, hyphens, and pluses.
check_assignment_or_regexp(:table_separator, /^\s*\|[-\|\+]*\s*$/)
end
# Checks if this line is a table header.
def table_header?
@assigned_paragraph_type == :table_header
end
def table?
table_row? or table_separator? or table_header?
end
BlockRegexp = /^\s*#\+(BEGIN|END)_(\w*)\s*([0-9A-Za-z_\-]*)?/i
def begin_block?
@line =~ BlockRegexp && $1 =~ /BEGIN/i
end
def end_block?
@line =~ BlockRegexp && $1 =~ /END/i
end
def block_type
$2 if @line =~ BlockRegexp
end
def block_lang
$3 if @line =~ BlockRegexp
end
def code_block?
block_type =~ /^(EXAMPLE|SRC)$/i
end
InlineExampleRegexp = /^\s*:\s/
# Test if the line matches the "inline example" case:
# the first character on the line is a colon.
def inline_example?
check_assignment_or_regexp(:inline_example, InlineExampleRegexp)
end
RawTextRegexp = /^(\s*)#\+(\w+):\s*/
# Checks if this line is raw text.
def raw_text?
check_assignment_or_regexp(:raw_text, RawTextRegexp)
end
def raw_text_tag
$2.upcase if @line =~ RawTextRegexp
end
def strip_raw_text_tag
@line.sub(RawTextRegexp) { |match| $1 }
end
InBufferSettingRegexp = /^#\+(\w+):\s*(.*)$/
# call-seq:
# line.in_buffer_setting? => boolean
# line.in_buffer_setting? { |key, value| ... }
#
# Called without a block, this method determines if the line
# contains an in-buffer setting. Called with a block, the block
# will get called if the line contains an in-buffer setting with
# the key and value for the setting.
def in_buffer_setting?
return false if @assigned_paragraph_type && @assigned_paragraph_type != :comment
if block_given? then
if @line =~ InBufferSettingRegexp
yield $1, $2
end
else
@line =~ InBufferSettingRegexp
end
end
# Determines the paragraph type of the current line.
def determine_paragraph_type
@paragraph_type = \
case
when blank?
:blank
when definition_list? # order is important! A definition_list is also an unordered_list!
:definition_term
when (ordered_list? or unordered_list?)
:list_item
when property_drawer_begin_block?
:property_drawer_begin_block
when property_drawer_end_block?
:property_drawer_end_block
when property_drawer_item?
:property_drawer_item
when metadata?
:metadata
when block_type
case block_type.downcase.to_sym
when :center, :comment, :example, :html, :quote, :src
block_type.downcase.to_sym
else
:comment
end
when raw_text? # order is important! Raw text can be also a comment
:raw_text
when comment?
:comment
when table_separator?
:table_separator
when table_row?
:table_row
when table_header?
:table_header
when inline_example?
:inline_example
when horizontal_rule?
:horizontal_rule
else :paragraph
end
end
def determine_major_mode
@major_mode = \
case
when definition_list? # order is important! A definition_list is also an unordered_list!
:definition_list
when ordered_list?
:ordered_list
when unordered_list?
:unordered_list
when table?
:table
end
end
######################################################################
private
# This function is an internal helper for determining the paragraph
# type of a line... for instance, if the line is a comment or contains
# metadata. It's used in routines like blank?, plain_list?, etc.
#
# What's tricky is lines can have assigned types, so you need to check
# the assigned type, if present, or see if the characteristic regexp
# for the paragraph type matches if not present.
#
# call-seq:
# check_assignment_or_regexp(assignment, regexp) => boolean
#
# assignment:: if the paragraph has an assigned type, it will be
# checked to see if it equals +assignment+.
# regexp:: If the paragraph does not have an assigned type,
# the contents of the paragraph will be checked against
# this regexp.
def check_assignment_or_regexp(assignment, regexp)
return @assigned_paragraph_type == assignment if @assigned_paragraph_type
return @line =~ regexp
end
end # class Line
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/output_buffer.rb 0000664 0000000 0000000 00000020353 12105711076 0021022 0 ustar 00root root 0000000 0000000 require 'logger'
module Orgmode
# The OutputBuffer is used to accumulate multiple lines of orgmode
# text, and then emit them to the output all in one go. The class
# will do the final textile substitution for inline formatting and
# add a newline character prior emitting the output.
class OutputBuffer
# This is the overall output buffer
attr_reader :output
# This is the current type of output being accumulated.
attr_accessor :output_type
# Creates a new OutputBuffer object that is bound to an output object.
# The output will get flushed to =output=.
def initialize(output)
# This is the accumulation buffer. It's a holding pen so
# consecutive lines of the right type can get stuck together
# without intervening newlines.
@buffer = ""
# This stack is used to do proper outline numbering of
# headlines.
@headline_number_stack = []
@output = output
@output_type = :start
@list_indent_stack = []
@mode_stack = []
@code_block_indent = nil
@logger = Logger.new(STDERR)
if ENV['DEBUG'] or $DEBUG
@logger.level = Logger::DEBUG
else
@logger.level = Logger::WARN
end
@re_help = RegexpHelper.new
end
def current_mode
@mode_stack.last
end
def push_mode(mode)
@mode_stack.push(mode)
end
def pop_mode(mode = nil)
m = @mode_stack.pop
@logger.warn "Modes don't match. Expected to pop #{mode}, but popped #{m}" if mode && mode != m
m
end
def insert(line)
# Prepares the output buffer to receive content from a line.
# As a side effect, this may flush the current accumulated text.
@logger.debug "Looking at #{line.paragraph_type}(#{current_mode}) : #{line.to_s}"
# We try to get the lang from #+BEGIN_SRC blocks
@block_lang = line.block_lang if line.begin_block?
unless should_accumulate_output?(line)
flush!
maintain_mode_stack(line)
end
# Adds the current line to the output buffer
case
when line.raw_text?
@buffer << "\n" << line.output_text if line.raw_text_tag == @buffer_tag
when preserve_whitespace?
@buffer << "\n" << line.output_text unless line.block_type
when line.assigned_paragraph_type == :code
# If the line is contained within a code block but we should
# not preserve whitespaces, then we do nothing.
when (line.kind_of? Headline)
add_line_attributes line
@buffer << "\n" << line.output_text.strip
when ([:definition_term, :list_item, :table_row, :table_header,
:horizontal_rule].include? line.paragraph_type)
@buffer << "\n" << line.output_text.strip
when line.paragraph_type == :paragraph
@buffer << "\n"
buffer_indentation
@buffer << line.output_text.strip
end
if mode_is_code? current_mode and not line.block_type
# Determines the amount of whitespaces to be stripped at the
# beginning of each line in code block.
if @code_block_indent
@code_block_indent = [@code_block_indent, line.indent].min
else
@code_block_indent = line.indent
end
end
@output_type = line.assigned_paragraph_type || line.paragraph_type
end
# Gets the next headline number for a given level. The intent is
# this function is called sequentially for each headline that
# needs to get numbered. It does standard outline numbering.
def get_next_headline_number(level)
raise "Headline level not valid: #{level}" if level <= 0
while level > @headline_number_stack.length do
@headline_number_stack.push 0
end
while level < @headline_number_stack.length do
@headline_number_stack.pop
end
raise "Oops, shouldn't happen" unless level == @headline_number_stack.length
@headline_number_stack[@headline_number_stack.length - 1] += 1
@headline_number_stack.join(".")
end
# Gets the current list indent level.
def list_indent_level
@list_indent_stack.length
end
# Test if we're in an output mode in which whitespace is significant.
def preserve_whitespace?
[:example, :inline_example, :raw_text, :src].include? current_mode
end
######################################################################
private
def mode_is_heading?(mode)
[:heading1, :heading2, :heading3,
:heading4, :heading5, :heading6].include? mode
end
def mode_is_block?(mode)
[:quote, :center, :example, :src].include? mode
end
def mode_is_code?(mode)
[:example, :src].include? mode
end
def boundary_of_block?(line)
# Boundary of inline example
return true if ((line.paragraph_type == :inline_example) ^
(@output_type == :inline_example))
# Boundary of begin...end block
return true if mode_is_block? @output_type
end
def maintain_mode_stack(line)
# Always close the following lines
pop_mode if (mode_is_heading? current_mode or
current_mode == :paragraph or
current_mode == :horizontal_rule or
current_mode == :inline_example or
current_mode == :raw_text)
# End-block line closes every mode within block
if line.end_block? and @mode_stack.include? line.paragraph_type
pop_mode until current_mode == line.paragraph_type
end
if ((not line.paragraph_type == :blank) or
@output_type == :blank)
# Close previous tags on demand. Two blank lines close all tags.
while ((not @list_indent_stack.empty?) and
@list_indent_stack.last >= line.indent and
# Don't allow an arbitrary line to close block
(not mode_is_block? current_mode))
# Item can't close its major mode
if (@list_indent_stack.last == line.indent and
line.major_mode == current_mode)
break
else
pop_mode
end
end
end
# Special case: Only end-block line closes block
pop_mode if line.end_block? and line.paragraph_type == current_mode
unless line.paragraph_type == :blank
if (@list_indent_stack.empty? or
@list_indent_stack.last <= line.indent or
mode_is_block? current_mode)
# Opens the major mode of line if it exists
if @list_indent_stack.last != line.indent or mode_is_block? current_mode
push_mode(line.major_mode, line.indent) if line.major_mode
end
# Opens tag that precedes text immediately
push_mode(line.paragraph_type, line.indent) unless line.end_block?
end
end
end
def output_footnotes!
return false
end
# Tests if the current line should be accumulated in the current
# output buffer.
def should_accumulate_output? line
# Special case: Assign mode if not yet done.
return false unless current_mode
# Special case: Handles accumulating block content and example lines
if mode_is_code? current_mode
return true unless (line.end_block? and
line.paragraph_type == current_mode)
end
return false if boundary_of_block? line
return true if current_mode == :inline_example
# Special case: Don't accumulate the following lines.
return false if (mode_is_heading? @output_type or
@output_type == :comment or
@output_type == :horizontal_rule or
@output_type == :raw_text)
# Special case: Blank line at least splits paragraphs
return false if @output_type == :blank
if line.paragraph_type == :paragraph
# Paragraph gets accumulated only if its indent level is
# greater than the indent level of the previous mode.
if @mode_stack[-2] and not mode_is_block? @mode_stack[-2]
return false if line.indent <= @list_indent_stack[-2]
end
# Special case: Multiple "paragraphs" get accumulated.
return true
end
false
end
def buffer_indentation
return false
end
end # class OutputBuffer
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/parser.rb 0000664 0000000 0000000 00000023117 12105711076 0017426 0 ustar 00root root 0000000 0000000 require 'rubypants'
module Orgmode
##
## Simple routines for loading / saving an ORG file.
##
class Parser
# All of the lines of the orgmode file
attr_reader :lines
# All of the headlines in the org file
attr_reader :headlines
# These are any lines before the first headline
attr_reader :header_lines
# This contains any in-buffer settings from the org-mode file.
# See http://orgmode.org/manual/In_002dbuffer-settings.html#In_002dbuffer-settings
attr_reader :in_buffer_settings
# This contains in-buffer options; a special case of in-buffer settings.
attr_reader :options
# Array of custom keywords.
attr_reader :custom_keywords
# Regexp that recognizes words in custom_keywords.
def custom_keyword_regexp
return nil if @custom_keywords.empty?
Regexp.new("^(#{@custom_keywords.join('|')})\$")
end
# A set of tags that, if present on any headlines in the org-file, means
# only those headings will get exported.
def export_select_tags
return Array.new unless @in_buffer_settings["EXPORT_SELECT_TAGS"]
@in_buffer_settings["EXPORT_SELECT_TAGS"].split
end
# A set of tags that, if present on any headlines in the org-file, means
# that subtree will not get exported.
def export_exclude_tags
return Array.new unless @in_buffer_settings["EXPORT_EXCLUDE_TAGS"]
@in_buffer_settings["EXPORT_EXCLUDE_TAGS"].split
end
# Returns true if we are to export todo keywords on headings.
def export_todo?
"t" == @options["todo"]
end
# Returns true if we are to export footnotes
def export_footnotes?
"t" == @options["f"]
end
# Returns true if we are to export heading numbers.
def export_heading_number?
"t" == @options["num"]
end
# Should we skip exporting text before the first heading?
def skip_header_lines?
"t" == @options["skip"]
end
# Should we export tables? Defaults to true, must be overridden
# with an explicit "nil"
def export_tables?
"nil" != @options["|"]
end
# Should we export sub/superscripts? (_{foo}/^{foo})
# only {} mode is currently supported.
def use_sub_superscripts?
@options["^"] != "nil"
end
# I can construct a parser object either with an array of lines
# or with a single string that I will split along \n boundaries.
def initialize(lines, offset=0)
if lines.is_a? Array then
@lines = lines
elsif lines.is_a? String then
@lines = lines.split("\n")
else
raise "Unsupported type for +lines+: #{lines.class}"
end
@custom_keywords = []
@headlines = Array.new
@current_headline = nil
@header_lines = []
@in_buffer_settings = { }
@options = { }
mode = :normal
previous_line = nil
table_header_set = false
@lines.each do |text|
line = Line.new text, self
mode = :normal if line.end_block? and mode == line.paragraph_type
mode = :normal if line.property_drawer_end_block? and mode == :property_drawer
case mode
when :normal, :quote, :center
if Headline.headline? line.line
line = Headline.new line.line, self, offset
elsif line.table_separator?
if previous_line and previous_line.paragraph_type == :table_row and !table_header_set
previous_line.assigned_paragraph_type = :table_header
table_header_set = true
end
end
table_header_set = false if !line.table?
when :example, :html, :src
# As long as we stay in code mode, force lines to be code.
# Don't try to interpret structural items, like headings and tables.
line.assigned_paragraph_type = :code
end
if mode == :normal
@headlines << @current_headline = line if Headline.headline? line.line
# If there is a setting on this line, remember it.
line.in_buffer_setting? do |key, value|
store_in_buffer_setting key.upcase, value
end
mode = line.paragraph_type if line.begin_block?
mode = :property_drawer if line.property_drawer_begin_block?
end
unless mode == :comment
if @current_headline
@current_headline.body_lines << line
else
@header_lines << line
end
end
previous_line = line
end # @lines.each
end # initialize
# Creates a new parser from the data in a given file
def self.load(fname)
lines = IO.readlines(fname)
return self.new(lines)
end
# Saves the loaded orgmode file as a textile file.
def to_textile
output = ""
output_buffer = TextileOutputBuffer.new(output)
translate(@header_lines, output_buffer)
@headlines.each do |headline|
translate(headline.body_lines, output_buffer)
end
output
end
# Converts the loaded org-mode file to HTML.
def to_html
mark_trees_for_export
export_options = {
:decorate_title => @in_buffer_settings["TITLE"],
:export_heading_number => export_heading_number?,
:export_todo => export_todo?,
:use_sub_superscripts => use_sub_superscripts?,
:export_footnotes => export_footnotes?
}
export_options[:skip_tables] = true if not export_tables?
output = ""
output_buffer = HtmlOutputBuffer.new(output, export_options)
if @in_buffer_settings["TITLE"] then
# If we're given a new title, then just create a new line
# for that title.
title = Line.new(@in_buffer_settings["TITLE"], self)
translate([title], output_buffer)
end
translate(@header_lines, output_buffer) unless skip_header_lines?
# If we've output anything at all, remove the :decorate_title option.
export_options.delete(:decorate_title) if (output.length > 0)
@headlines.each do |headline|
next if headline.export_state == :exclude
case headline.export_state
when :exclude
# NOTHING
when :headline_only
translate(headline.body_lines[0, 1], output_buffer)
when :all
translate(headline.body_lines, output_buffer)
end
end
output << "\n"
rp = RubyPants.new(output)
rp.to_html
end
######################################################################
private
# Converts an array of lines to the appropriate format.
# Writes the output to +output_buffer+.
def translate(lines, output_buffer)
output_buffer.output_type = :start
lines.each { |line| output_buffer.insert(line) }
output_buffer.flush!
output_buffer.pop_mode while output_buffer.current_mode
output_buffer.output_footnotes!
output_buffer.output
end
# Uses export_select_tags and export_exclude_tags to determine
# which parts of the org-file to export.
def mark_trees_for_export
marked_any = false
# cache the tags
select = export_select_tags
exclude = export_exclude_tags
inherit_export_level = nil
ancestor_stack = []
# First pass: See if any headlines are explicitly selected
@headlines.each do |headline|
ancestor_stack.pop while not ancestor_stack.empty? and headline.level <= ancestor_stack.last.level
if inherit_export_level and headline.level > inherit_export_level
headline.export_state = :all
else
inherit_export_level = nil
headline.tags.each do |tag|
if (select.include? tag) then
marked_any = true
headline.export_state = :all
ancestor_stack.each { |a| a.export_state = :headline_only unless a.export_state == :all }
inherit_export_level = headline.level
end
end
end
ancestor_stack.push headline
end
# If nothing was selected, then EVERYTHING is selected.
@headlines.each { |h| h.export_state = :all } unless marked_any
# Second pass. Look for things that should be excluded, and get rid of them.
@headlines.each do |headline|
if inherit_export_level and headline.level > inherit_export_level
headline.export_state = :exclude
else
inherit_export_level = nil
headline.tags.each do |tag|
if (exclude.include? tag) then
headline.export_state = :exclude
inherit_export_level = headline.level
end
end
if headline.comment_headline?
headline.export_state = :exclude
inherit_export_level = headline.level
end
end
end
end
# Stores an in-buffer setting.
def store_in_buffer_setting(key, value)
if key == "OPTIONS" then
# Options are stored in a hash. Special-case.
value.split.each do |opt|
if opt =~ /^(.*):(.*?)$/ then
@options[$1] = $2
else
raise "Unexpected option: #{opt}"
end
end
elsif key =~ /^(TODO|SEQ_TODO|TYP_TODO)$/ then
# Handle todo keywords specially.
value.split.each do |keyword|
keyword.gsub!(/\(.*\)/, "") # Get rid of any parenthetical notes
keyword = Regexp.escape(keyword)
next if keyword == "\\|" # Special character in the todo format, not really a keyword
@custom_keywords << keyword
end
else
@in_buffer_settings[key] = value
end
end
end # class Parser
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/regexp_helper.rb 0000664 0000000 0000000 00000015202 12105711076 0020757 0 ustar 00root root 0000000 0000000 require 'logger'
module Orgmode
# = Summary
#
# This class contains helper routines to deal with the Regexp "black
# magic" you need to properly parse org-mode files.
#
# = Key methods
#
# * Use +rewrite_emphasis+ to replace org-mode emphasis strings (e.g.,
# \/italic/) with the suitable markup for the output.
#
# * Use +rewrite_links+ to get a chance to rewrite all org-mode
# links with suitable markup for the output.
#
# * Use +rewrite_images+ to rewrite all inline image links with suitable
# markup for the output.
class RegexpHelper
######################################################################
# EMPHASIS
#
# I figure it's best to stick as closely to the elisp implementation
# as possible for emphasis. org.el defines the regular expression that
# is used to apply "emphasis" (in my terminology, inline formatting
# instead of block formatting). Here's the documentation from org.el.
#
# Terminology: In an emphasis string like " *strong word* ", we
# call the initial space PREMATCH, the final space POSTMATCH, the
# stars MARKERS, "s" and "d" are BORDER characters and "trong wor"
# is the body. The different components in this variable specify
# what is allowed/forbidden in each part:
#
# pre Chars allowed as prematch. Line beginning allowed, too.
# post Chars allowed as postmatch. Line end will be allowed too.
# border The chars *forbidden* as border characters.
# body-regexp A regexp like \".\" to match a body character. Don't use
# non-shy groups here, and don't allow newline here.
# newline The maximum number of newlines allowed in an emphasis exp.
attr_reader :org_image_file_regexp
def initialize
# Set up the emphasis regular expression.
@pre_emphasis = ' \t\(\'"\{'
@post_emphasis = '- \t\.,:!\?;\'"\)\}\\\\'
@border_forbidden = '\s,"\''
@body_regexp = '.*?'
@max_newlines = 1
@body_regexp = "#{@body_regexp}" +
"(?:\\n#{@body_regexp}){0,#{@max_newlines}}" if @max_newlines > 0
@markers = '\*\/_=~\+'
@code_snippet_stack = []
@logger = Logger.new(STDERR)
@logger.level = Logger::WARN
build_org_emphasis_regexp
build_org_link_regexp
@org_subp_regexp = /([_^])\{(.*?)\}/
@org_footnote_regexp = /\[fn:(.+?)(:(.*?))?\]/
end
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
# Compute replacements for all matching emphasized phrases.
# Supply a block that will get the marker and body as parameters;
# return the replacement string from your block.
#
# = Example
#
# re = RegexpHelper.new
# result = re.rewrite_emphasis("*bold*, /italic/, =code=") do |marker, body|
# "<#{map[marker]}>#{body}#{map[marker]}>"
# end
#
# In this example, the block body will get called three times:
#
# 1. Marker: "*", body: "bold"
# 2. Marker: "/", body: "italic"
# 3. Marker: "=", body: "code"
#
# The return from this block is a string that will be used to
# replace "*bold*", "/italic/", and "=code=",
# respectively. (Clearly this sample string will use HTML-like
# syntax, assuming +map+ is defined appropriately.)
def rewrite_emphasis str
# escape the percent signs for safe restoring code snippets
str.gsub!(/%/, "%%")
format_str = "%s"
str.gsub! @org_emphasis_regexp do |match|
# preserve the code snippet from further formatting
inner = if $2 == "=" or $2 == "~"
@code_snippet_stack.push $3
yield $2, format_str
else
yield $2, $3
end
"#{$1}#{inner}"
end
end
# rewrite subscript and superscript (_{foo} and ^{bar})
def rewrite_subp str # :yields: type ("_" for subscript and "^" for superscript), text
str.gsub! @org_subp_regexp do |match|
yield $1, $2
end
end
# rewrite footnotes
def rewrite_footnote str # :yields: name, definition or nil
str.gsub! @org_footnote_regexp do |match|
yield $1, $3
end
end
# = Summary
#
# Rewrite org-mode links in a string to markup suitable to the
# output format.
#
# = Usage
#
# Give this a block that expect the link and optional friendly
# text. Return how that link should get formatted.
#
# = Example
#
# re = RegexpHelper.new
# result = re.rewrite_links("[[http://www.bing.com]] and [[http://www.hotmail.com][Hotmail]]") do |link, text}
# text ||= link
# "#{text}"
# end
#
# In this example, the block body will get called two times. In the
# first instance, +text+ will be nil (the org-mode markup gives no
# friendly text for the link +http://www.bing.com+. In the second
# instance, the block will get text of *Hotmail* and the link
# +http://www.hotmail.com+. In both cases, the block returns an
# HTML-style link, and that is how things will get recorded in
# +result+.
def rewrite_links str # :yields: link, text
str.gsub! @org_link_regexp do |match|
yield $1, $3
end
str.gsub! @org_angle_link_text_regexp do |match|
yield $1, nil
end
str # for testing
end
def restore_code_snippets str
str = str % @code_snippet_stack
@code_snippet_stack = []
str
end
private
def build_org_emphasis_regexp
@org_emphasis_regexp = Regexp.new("([#{@pre_emphasis}]|^)" +
"([#{@markers}])(?!\\2)" +
"([^#{@border_forbidden}]|" +
"[^#{@border_forbidden}]#{@body_regexp}" +
"[^#{@border_forbidden}])\\2" +
"(?=[#{@post_emphasis}]|$)")
@logger.debug "Just created regexp: #{@org_emphasis_regexp}"
end
def build_org_link_regexp
@org_link_regexp = /\[\[
([^\]\[]+) # This is the URL
\](\[
([^\]\[]+) # This is the friendly text
\])?\]/x
@org_angle_link_text_regexp = /<(\w+:[^\]\s<>]+)>/
@org_image_file_regexp = /\.(gif|jpe?g|p(?:bm|gm|n[gm]|pm)|svg|tiff?|x[bp]m)/i
end
end # class Emphasis
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/textile_output_buffer.rb 0000664 0000000 0000000 00000010561 12105711076 0022560 0 ustar 00root root 0000000 0000000 require 'stringio'
module Orgmode
class TextileOutputBuffer < OutputBuffer
def initialize(output)
super(output)
@add_paragraph = true
@support_definition_list = true # TODO this should be an option
@footnotes = []
end
def push_mode(mode, indent)
@list_indent_stack.push(indent)
super(mode)
@output << "bc. " if mode_is_code? mode
if mode == :center or mode == :quote
@add_paragraph = false
@output << "\n"
end
end
def pop_mode(mode = nil)
m = super(mode)
@list_indent_stack.pop
if m == :center or m == :quote
@add_paragraph = true
@output << "\n"
end
m
end
# Maps org markup to textile markup.
TextileMap = {
"*" => "*",
"/" => "_",
"_" => "_",
"=" => "@",
"~" => "@",
"+" => "+"
}
# Handles inline formatting for textile.
def inline_formatting(input)
@re_help.rewrite_emphasis input do |marker, body|
m = TextileMap[marker]
"#{m}#{body}#{m}"
end
@re_help.rewrite_subp input do |type, text|
if type == "_" then
"~#{text}~"
elsif type == "^" then
"^#{text}^"
end
end
@re_help.rewrite_links input do |link, defi|
[link, defi].compact.each do |text|
# We don't support search links right now. Get rid of it.
text.sub!(/\A(file:[^\s]+)::[^\s]*?\Z/, "\\1")
text.sub!(/\A(file:[^\s]+)\.org\Z/i, "\\1.textile")
text.sub!(/\Afile:(?=[^\s]+\Z)/, "")
end
# We don't add a description for images in links, because its
# empty value forces the image to be inlined.
defi ||= link unless link =~ @re_help.org_image_file_regexp
link = link.gsub(/ /, "%%20")
if defi =~ @re_help.org_image_file_regexp
defi = "!#{defi}(#{defi})!"
elsif defi
defi = "\"#{defi}\""
end
if defi
"#{defi}:#{link}"
else
"!#{link}(#{link})!"
end
end
@re_help.rewrite_footnote input do |name, definition|
# textile only support numerical names, so we need to do some conversion
# Try to find the footnote and use its index
footnote = @footnotes.select {|f| f[:name] == name }.first
if footnote
# The latest definition overrides other ones
footnote[:definition] = definition if definition and not footnote[:definition]
else
# There is no footnote with the current name so we add it
footnote = { :name => name, :definition => definition }
@footnotes << footnote
end
"[#{@footnotes.index(footnote)}]"
end
Orgmode.special_symbols_to_textile(input)
input = @re_help.restore_code_snippets input
input
end
def output_footnotes!
return false if @footnotes.empty?
@footnotes.each do |footnote|
index = @footnotes.index(footnote)
@output << "\nfn#{index}. #{footnote[:definition] || 'DEFINITION NOT FOUND' }\n"
end
return true
end
# Flushes the current buffer
def flush!
return false if @buffer.empty? and @output_type != :blank
@logger.debug "FLUSH ==========> #{@output_type}"
@buffer.gsub!(/\A\n*/, "")
case
when preserve_whitespace?
@output << @buffer << "\n"
when @output_type == :blank
@output << "\n"
else
case current_mode
when :paragraph
@output << "p. " if @add_paragraph
@output << "p=. " if @mode_stack[0] == :center
@output << "bq. " if @mode_stack[0] == :quote
when :list_item
if @mode_stack[-2] == :ordered_list
@output << "#" * @mode_stack.count(:list_item) << " "
else # corresponds to unordered list
@output << "*" * @mode_stack.count(:list_item) << " "
end
when :definition_term
if @support_definition_list
@output << "-" * @mode_stack.count(:definition_term) << " "
@buffer.sub!("::", ":=")
end
end
@output << inline_formatting(@buffer) << "\n"
end
@buffer = ""
end
def add_line_attributes headline
@output << "h#{headline.level}. "
end
end # class TextileOutputBuffer
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/textile_symbol_replace.rb 0000664 0000000 0000000 00000017255 12105711076 0022676 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Autogenerated by util/gen-special-replace.el
module Orgmode
TextileEntities = {
"Agrave" => "À",
"agrave" => "à",
"Aacute" => "Á",
"aacute" => "á",
"Acirc" => "Â",
"acirc" => "â",
"Atilde" => "Ã",
"atilde" => "ã",
"Auml" => "Ä",
"auml" => "ä",
"Aring" => "Å",
"AA" => "Å",
"aring" => "å",
"AElig" => "Æ",
"aelig" => "æ",
"Ccedil" => "Ç",
"ccedil" => "ç",
"Egrave" => "È",
"egrave" => "è",
"Eacute" => "É",
"eacute" => "é",
"Ecirc" => "Ê",
"ecirc" => "ê",
"Euml" => "Ë",
"euml" => "ë",
"Igrave" => "Ì",
"igrave" => "ì",
"Iacute" => "Í",
"iacute" => "í",
"Icirc" => "Î",
"icirc" => "î",
"Iuml" => "Ï",
"iuml" => "ï",
"Ntilde" => "Ñ",
"ntilde" => "ñ",
"Ograve" => "Ò",
"ograve" => "ò",
"Oacute" => "Ó",
"oacute" => "ó",
"Ocirc" => "Ô",
"ocirc" => "ô",
"Otilde" => "Õ",
"otilde" => "õ",
"Ouml" => "Ö",
"ouml" => "ö",
"Oslash" => "Ø",
"oslash" => "ø",
"OElig" => "Œ",
"oelig" => "œ",
"Scaron" => "Š",
"scaron" => "š",
"szlig" => "ß",
"Ugrave" => "Ù",
"ugrave" => "ù",
"Uacute" => "Ú",
"uacute" => "ú",
"Ucirc" => "Û",
"ucirc" => "û",
"Uuml" => "Ü",
"uuml" => "ü",
"Yacute" => "Ý",
"yacute" => "ý",
"Yuml" => "Ÿ",
"yuml" => "ÿ",
"fnof" => "ƒ",
"real" => "ℜ",
"image" => "ℑ",
"weierp" => "℘",
"Alpha" => "Α",
"alpha" => "α",
"Beta" => "Β",
"beta" => "β",
"Gamma" => "Γ",
"gamma" => "γ",
"Delta" => "Δ",
"delta" => "δ",
"Epsilon" => "Ε",
"epsilon" => "ε",
"varepsilon" => "ε",
"Zeta" => "Ζ",
"zeta" => "ζ",
"Eta" => "Η",
"eta" => "η",
"Theta" => "Θ",
"theta" => "θ",
"thetasym" => "ϑ",
"vartheta" => "ϑ",
"Iota" => "Ι",
"iota" => "ι",
"Kappa" => "Κ",
"kappa" => "κ",
"Lambda" => "Λ",
"lambda" => "λ",
"Mu" => "Μ",
"mu" => "μ",
"nu" => "ν",
"Nu" => "Ν",
"Xi" => "Ξ",
"xi" => "ξ",
"Omicron" => "Ο",
"omicron" => "ο",
"Pi" => "Π",
"pi" => "π",
"Rho" => "Ρ",
"rho" => "ρ",
"Sigma" => "Σ",
"sigma" => "σ",
"sigmaf" => "ς",
"varsigma" => "ς",
"Tau" => "Τ",
"Upsilon" => "Υ",
"upsih" => "ϒ",
"upsilon" => "υ",
"Phi" => "Φ",
"phi" => "φ",
"Chi" => "Χ",
"chi" => "χ",
"acutex" => "𝑥́",
"Psi" => "Ψ",
"psi" => "ψ",
"tau" => "τ",
"Omega" => "Ω",
"omega" => "ω",
"piv" => "ϖ",
"partial" => "∂",
"alefsym" => "ℵ",
"ETH" => "Ð",
"eth" => "ð",
"THORN" => "Þ",
"thorn" => "þ",
"dots" => "…",
"hellip" => "…",
"middot" => "·",
"iexcl" => "¡",
"iquest" => "¿",
"shy" => "",
"ndash" => "–",
"mdash" => "—",
"quot" => "\"",
"acute" => "´",
"ldquo" => "“",
"rdquo" => "”",
"bdquo" => "„",
"lsquo" => "‘",
"rsquo" => "’",
"sbquo" => "‚",
"laquo" => "«",
"raquo" => "»",
"lsaquo" => "‹",
"rsaquo" => "›",
"circ" => "ˆ",
"vert" => "|",
"brvbar" => "¦",
"sect" => "§",
"amp" => "&",
"lt" => "<",
"gt" => ">",
"tilde" => "~",
"slash" => "/",
"plus" => "+",
"under" => "_",
"equal" => "=",
"asciicirc" => "^",
"dagger" => "†",
"Dagger" => "‡",
"nbsp" => " ",
"ensp" => " ",
"emsp" => " ",
"thinsp" => " ",
"curren" => "¤",
"cent" => "¢",
"pound" => "£",
"yen" => "¥",
"euro" => "€",
"EUR" => "€",
"EURdig" => "€",
"EURhv" => "€",
"EURcr" => "€",
"EURtm" => "€",
"copy" => "©",
"reg" => "®",
"trade" => "™",
"minus" => "−",
"pm" => "±",
"plusmn" => "±",
"times" => "×",
"frasl" => "⁄",
"div" => "÷",
"frac12" => "½",
"frac14" => "¼",
"frac34" => "¾",
"permil" => "‰",
"sup1" => "¹",
"sup2" => "²",
"sup3" => "³",
"radic" => "√",
"sum" => "∑",
"prod" => "∏",
"micro" => "µ",
"macr" => "¯",
"deg" => "°",
"prime" => "′",
"Prime" => "″",
"infin" => "∞",
"infty" => "∞",
"prop" => "∝",
"proptp" => "∝",
"not" => "¬",
"neg" => "¬",
"land" => "∧",
"wedge" => "∧",
"lor" => "∨",
"vee" => "∨",
"cap" => "∩",
"cup" => "∪",
"int" => "∫",
"there4" => "∴",
"sim" => "∼",
"cong" => "≅",
"simeq" => "≅",
"asymp" => "≈",
"approx" => "≈",
"ne" => "≠",
"neq" => "≠",
"equiv" => "≡",
"le" => "≤",
"ge" => "≥",
"sub" => "⊂",
"subset" => "⊂",
"sup" => "⊃",
"supset" => "⊃",
"nsub" => "⊄",
"sube" => "⊆",
"nsup" => "⊅",
"supe" => "⊇",
"forall" => "∀",
"exist" => "∃",
"exists" => "∃",
"empty" => "∅",
"emptyset" => "∅",
"isin" => "∈",
"in" => "∈",
"notin" => "∉",
"ni" => "∋",
"nabla" => "∇",
"ang" => "∠",
"angle" => "∠",
"perp" => "⊥",
"sdot" => "⋅",
"cdot" => "⋅",
"lceil" => "⌈",
"rceil" => "⌉",
"lfloor" => "⌊",
"rfloor" => "⌋",
"lang" => "⟨",
"rang" => "⟩",
"larr" => "←",
"leftarrow" => "←",
"gets" => "←",
"lArr" => "⇐",
"Leftarrow" => "⇐",
"uarr" => "↑",
"uparrow" => "↑",
"uArr" => "⇑",
"Uparrow" => "⇑",
"rarr" => "→",
"to" => "→",
"rightarrow" => "→",
"rArr" => "⇒",
"Rightarrow" => "⇒",
"darr" => "↓",
"downarrow" => "↓",
"dArr" => "⇓",
"Downarrow" => "⇓",
"harr" => "↔",
"leftrightarrow" => "↔",
"hArr" => "⇔",
"Leftrightarrow" => "⇔",
"crarr" => "↵",
"hookleftarrow" => "↵",
"arccos" => "arccos",
"arcsin" => "arcsin",
"arctan" => "arctan",
"arg" => "arg",
"cos" => "cos",
"cosh" => "cosh",
"cot" => "cot",
"coth" => "coth",
"csc" => "csc",
"deg" => "deg",
"det" => "det",
"dim" => "dim",
"exp" => "exp",
"gcd" => "gcd",
"hom" => "hom",
"inf" => "inf",
"ker" => "ker",
"lg" => "lg",
"lim" => "lim",
"liminf" => "liminf",
"limsup" => "limsup",
"ln" => "ln",
"log" => "log",
"max" => "max",
"min" => "min",
"Pr" => "Pr",
"sec" => "sec",
"sin" => "sin",
"sinh" => "sinh",
"sup" => "sup",
"tan" => "tan",
"tanh" => "tanh",
"bull" => "•",
"bullet" => "•",
"star" => "⋆",
"lowast" => "∗",
"ast" => "*",
"odot" => "ʘ",
"oplus" => "⊕",
"otimes" => "⊗",
"checkmark" => "✓",
"para" => "¶",
"ordf" => "ª",
"ordm" => "º",
"cedil" => "¸",
"oline" => "‾",
"uml" => "¨",
"zwnj" => "",
"zwj" => "",
"lrm" => "",
"rlm" => "",
"smile" => "⌣",
"smiley" => "☺",
"blacksmile" => "☻",
"sad" => "☹",
"clubs" => "♣",
"clubsuit" => "♣",
"spades" => "♠",
"spadesuit" => "♠",
"hearts" => "♥",
"heartsuit" => "♥",
"diams" => "♦",
"diamondsuit" => "♦",
"Diamond" => "⋄",
"loz" => "◊"
}
@org_entities_regexp = /\\(there4|sup[123]|frac[13][24]|[a-zA-Z]+)($|\{\}|[^a-zA-Z])/
def Orgmode.special_symbols_to_textile str
str.gsub! @org_entities_regexp do |match|
if TextileEntities[$1]
if $2 == "{}" then "#{TextileEntities[$1]}"
else "#{TextileEntities[$1]}#{$2}"
end
else
$&
end
end
end
end # module Orgmode
ruby-org-0.8.0/lib/org-ruby/tilt.rb 0000664 0000000 0000000 00000000762 12105711076 0017107 0 ustar 00root root 0000000 0000000 begin
require 'tilt'
module Tilt
class OrgTemplate < Template
def self.engine_initialized?
defined? ::Orgmode
end
def initialize_engine
require 'org-ruby'
end
def prepare
@engine = Orgmode::Parser.new(data)
@output = nil
end
def evaluate(scope, locals, &block)
@output ||= @engine.to_html
end
end
end
Tilt.register Tilt::OrgTemplate, 'org'
rescue LoadError
# Tilt is not available.
end
ruby-org-0.8.0/org-ruby.gemspec 0000664 0000000 0000000 00000003355 12105711076 0016406 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
s.name = "org-ruby"
s.version = "0.8.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Brian Dewey"]
s.date = "2012-10-07"
s.description = "This gem contains Ruby routines for parsing org-mode files.The most\nsignificant thing this library does today is convert org-mode files to\nHTML or textile. Currently, you cannot do much to customize the\nconversion. The supplied textile conversion is optimized for\nextracting \"content\" from the orgfile as opposed to \"metadata.\" "
s.email = "bdewey@gmail.com"
s.executables = ["org-ruby"]
s.extra_rdoc_files = ["History.txt", "README.rdoc", "bin/org-ruby"]
s.files = ["History.txt", "README.rdoc", "bin/org-ruby", "lib/org-ruby.rb", "lib/org-ruby/headline.rb", "lib/org-ruby/html_output_buffer.rb", "lib/org-ruby/html_symbol_replace.rb", "lib/org-ruby/line.rb", "lib/org-ruby/output_buffer.rb", "lib/org-ruby/parser.rb", "lib/org-ruby/regexp_helper.rb", "lib/org-ruby/textile_output_buffer.rb", "lib/org-ruby/textile_symbol_replace.rb", "lib/org-ruby/tilt.rb"]
s.homepage = "http://github.com/bdewey/org-ruby"
s.rdoc_options = ["--main", "README.rdoc"]
s.require_paths = ["lib"]
s.rubyforge_project = "org-ruby"
s.rubygems_version = "1.8.10"
s.summary = "This gem contains Ruby routines for parsing org-mode files."
if s.respond_to? :specification_version then
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q, [">= 0.2.0"])
else
s.add_dependency(%q, [">= 0.2.0"])
end
else
s.add_dependency(%q, [">= 0.2.0"])
end
end
ruby-org-0.8.0/spec/ 0000775 0000000 0000000 00000000000 12105711076 0014217 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/spec/data/ 0000775 0000000 0000000 00000000000 12105711076 0015130 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/spec/data/freeform-example.org 0000664 0000000 0000000 00000007705 12105711076 0021110 0 ustar 00root root 0000000 0000000 #+BEGIN_EXAMPLE
#+TITLE: Freeform
#+AUTHOR:
#+EMAIL: bdewey@gmail.com
#+DATE: 2009-12-20 Sun
#+DESCRIPTION:
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
#+END_EXAMPLE
Freeform
This is my todo list, research file, and log record from working on
the Freeform project.
* Future ideas :someday:
- Add *posts*
- Enforce uniqueness of url_token
- Add FeedSync support
- Auto-recognize URLs
- Edit in place
- Import/export of content. I want it to be safe to store real content on the site.
- Page reordering.
- AtomPub support.
- Organization:
- Move pages around
- Add tags and navigation by tags
- Add a breadcrumb bar
* TODO Add versioning support :current:feature:
** DONE UI rough-in
CLOSED: [2009-11-26 Thu]
** DONE Author logging
CLOSED: [2009-11-27 Fri]
** DONE Version table and model updates
CLOSED: [2009-11-28 Sat 22:40]
CLOCK: [2009-11-28 Sat 21:35]--[2009-11-28 Sat 22:40] => 1:05
CLOCK: [2009-11-28 Sat 21:01]--[2009-11-28 Sat 21:25] => 0:24
CLOCK: [2009-11-28 Sat 19:46]--[2009-11-28 Sat 20:54] => 1:08
CLOCK: [2009-11-28 Sat 14:38]--[2009-11-28 Sat 15:08] => 0:30
CLOCK: [2009-11-28 Sat 13:21]--[2009-11-28 Sat 14:37] => 1:16
OK, my current thinking is to have each idea have many Changes. A
change has many change records. A change record is a list of
specific attributes that change, and includes the old and the new
values. I'll use callbacks on the Idea model to maintain the
changes.
*** DONE Create version method
CLOSED: [2009-11-28 Sat 22:40]
*** DONE Make current method
CLOSED: [2009-11-28 Sat 22:40]
** Update pages controller
*** DONE Show versions
CLOSED: [2009-11-30 Mon 00:34]
CLOCK: [2009-11-29 Sun 21:27]--[2009-11-29 Sun 21:54] => 0:27
CLOCK: [2009-11-29 Sun 15:40]--[2009-11-29 Sun 15:44] => 0:04
CLOCK: [2009-11-28 Sat 22:44]--[2009-11-28 Sat 23:50] => 1:06
I'm now at the point where I *list* versions, but I can't show
them.
- [X] I currently suspect that I broke my version recovery code
when I switched the order of the idea_changes. I need to
investigate why nothing's failing in the tests; I expected
failures. Possible addition to test: start looking at those
version numbers.
OK, here's what was going on: In the test, you need to
reload the idea_changes array from the database to get the
database sort order. I also make sure I do this inside the
Idea methods.
**** DONE Write a test for Idea::attributes_for_change
CLOSED: [2009-11-29 Sun 23:59]
CLOCK: [2009-11-29 Sun 23:47]--[2009-11-29 Sun 23:58] => 0:11
CLOCK: [2009-11-29 Sun 22:02]--[2009-11-29 Sun 23:42] => 1:40
CLOCK: [2009-11-29 Sun 21:54]--[2009-11-29 Sun 21:56] => 0:02
*** DONE Write integration tests that cover versions.
CLOSED: [2009-12-11 Fri 23:25]
CLOCK: [2009-12-11 Fri 20:27]--[2009-12-11 Fri 23:25] => 2:58
*** DONE Recover versions
CLOSED: [2009-12-12 Sat 22:09]
CLOCK: [2009-12-12 Sat 21:02]--[2009-12-12 Sat 22:09] => 1:07
CLOCK: [2009-12-12 Sat 20:13]--[2009-12-12 Sat 21:00] => 0:47
*** DONE Move to recycle bin
CLOSED: [2009-12-12 Sat 22:59]
CLOCK: [2009-12-12 Sat 22:23]--[2009-12-12 Sat 22:59] => 0:36
Note I'm avoiding logging delete operations because I'm presuming
there will be a recycle bin, and therefore the *pages* controller
will never actually delete files. At some point, when I want to
support full FeedSync, I'll need to tackle this.
The other timebomb: I don't know how well my logging scheme will
work when pages move. I don't yet know if I will address this in
the current sprint.
ruby-org-0.8.0/spec/data/freeform.org 0000664 0000000 0000000 00000007647 12105711076 0017464 0 ustar 00root root 0000000 0000000 #+TITLE: Freeform
#+AUTHOR:
#+EMAIL: bdewey@gmail.com
#+DATE: 2009-12-20 Sun
#+DESCRIPTION:
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
Freeform
This is my todo list, research file, and log record from working on
the Freeform project.
* Future ideas :someday:
- Add *posts*
- Enforce uniqueness of url_token
- Add FeedSync support
- Auto-recognize URLs
- Edit in place
- Import/export of content. I want it to be safe to store real content on the site.
- Page reordering.
- AtomPub support.
- Organization:
- Move pages around
- Add tags and navigation by tags
- Add a breadcrumb bar
* TODO Add versioning support :current:feature:
** DONE UI rough-in
CLOSED: [2009-11-26 Thu]
** DONE Author logging
CLOSED: [2009-11-27 Fri]
** DONE Version table and model updates
CLOSED: [2009-11-28 Sat 22:40]
CLOCK: [2009-11-28 Sat 21:35]--[2009-11-28 Sat 22:40] => 1:05
CLOCK: [2009-11-28 Sat 21:01]--[2009-11-28 Sat 21:25] => 0:24
CLOCK: [2009-11-28 Sat 19:46]--[2009-11-28 Sat 20:54] => 1:08
CLOCK: [2009-11-28 Sat 14:38]--[2009-11-28 Sat 15:08] => 0:30
CLOCK: [2009-11-28 Sat 13:21]--[2009-11-28 Sat 14:37] => 1:16
OK, my current thinking is to have each idea have many Changes. A
change has many change records. A change record is a list of
specific attributes that change, and includes the old and the new
values. I'll use callbacks on the Idea model to maintain the
changes.
*** DONE Create version method
CLOSED: [2009-11-28 Sat 22:40]
*** DONE Make current method
CLOSED: [2009-11-28 Sat 22:40]
** Update pages controller
*** DONE Show versions
CLOSED: [2009-11-30 Mon 00:34]
CLOCK: [2009-11-29 Sun 21:27]--[2009-11-29 Sun 21:54] => 0:27
CLOCK: [2009-11-29 Sun 15:40]--[2009-11-29 Sun 15:44] => 0:04
CLOCK: [2009-11-28 Sat 22:44]--[2009-11-28 Sat 23:50] => 1:06
I'm now at the point where I *list* versions, but I can't show
them.
- [X] I currently suspect that I broke my version recovery code
when I switched the order of the idea_changes. I need to
investigate why nothing's failing in the tests; I expected
failures. Possible addition to test: start looking at those
version numbers.
OK, here's what was going on: In the test, you need to
reload the idea_changes array from the database to get the
database sort order. I also make sure I do this inside the
Idea methods.
**** DONE Write a test for Idea::attributes_for_change
CLOSED: [2009-11-29 Sun 23:59]
CLOCK: [2009-11-29 Sun 23:47]--[2009-11-29 Sun 23:58] => 0:11
CLOCK: [2009-11-29 Sun 22:02]--[2009-11-29 Sun 23:42] => 1:40
CLOCK: [2009-11-29 Sun 21:54]--[2009-11-29 Sun 21:56] => 0:02
*** DONE Write integration tests that cover versions.
CLOSED: [2009-12-11 Fri 23:25]
CLOCK: [2009-12-11 Fri 20:27]--[2009-12-11 Fri 23:25] => 2:58
*** DONE Recover versions
CLOSED: [2009-12-12 Sat 22:09]
CLOCK: [2009-12-12 Sat 21:02]--[2009-12-12 Sat 22:09] => 1:07
CLOCK: [2009-12-12 Sat 20:13]--[2009-12-12 Sat 21:00] => 0:47
*** DONE Move to recycle bin
CLOSED: [2009-12-12 Sat 22:59]
CLOCK: [2009-12-12 Sat 22:23]--[2009-12-12 Sat 22:59] => 0:36
Note I'm avoiding logging delete operations because I'm presuming
there will be a recycle bin, and therefore the *pages* controller
will never actually delete files. At some point, when I want to
support full FeedSync, I'll need to tackle this.
The other timebomb: I don't know how well my logging scheme will
work when pages move. I don't yet know if I will address this in
the current sprint.
ruby-org-0.8.0/spec/data/hyp-planning.org 0000664 0000000 0000000 00000057342 12105711076 0020260 0 ustar 00root root 0000000 0000000 #+TITLE: Introduction to Hyper-V Pre-Planning and Planning
#+AUTHOR: Brian Dewey
#+EMAIL: bdewey@microsoft.com
#+DATE: December 9, 2009
#+DESCRIPTION:
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:nil
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:nil pri:nil tags:nil
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
* DONE Introduction
CLOSED: [2009-12-09 Wed 15:18]
CLOCK: [2009-12-09 Wed 15:00]--[2009-12-09 Wed 15:18] => 0:18
CLOCK: [2009-12-09 Wed 10:02]--[2009-12-09 Wed 10:14] => 0:12
The pre-planning activities for Hyper-V proceeded in three
phases. In the first phase, we identified and wrote down a set of
/business value propositions./ These are things we could pitch to
customers as new value they would get from using Windows 8. To wrap
up phase one, we worked with Mike Neil's team in Windows Server to
rank the business value propositions. This step ensured that COSD
and Windows Server operated from a common, agreed-upon set of
priorities.
For the second phase of pre-planning, we brainstormed all of the
features we would need to implement to deliver on the value
propositions from phase one. We captured a short description of each
potential feature in a one-page spec.
In the final phase of pre-planning, the dev team estimated how much
dev effort would be required to implement each feature.
By the numbers, our pre-planning work generated:
- 19 different value propositions
- 159 one-page specs
- A 770-line spreadsheet containing dev estimates
- 4.5 times the amount of dev work than we can tackle in a single release
Moving from pre-planning to planning, our objective has been to
understand and to shape overall Windows priorities so we can pick
the /right/ 20% of work to commit to for Windows 8.
This document gives an overview of the different pre-planning
activities we did. It provides pointers to the pre-planning
artefacts we produced and shows how we've been able to map our
pre-planning work into planning.
* Business Value Propositions
CLOCK: [2009-12-07 Mon 09:09]--[2009-12-07 Mon 09:50] => 0:41
CLOSED: [2009-12-01 Tue 10:52]
One of the first pre-planning activities we did in Hyper-V was
define a set of /business value propositions/ (BVPs). A business value
proposition is an end-to-end hook that can convince a customer that
Windows 8 is worth buying.
Our BVPs are stored in the [[http://windows/hyper-v/initiatives/Value%20Propositions/Forms/AllItems.aspx][Hyper-V Portal]].
** Anatomy of a BVP
Each BVP followed a simple, one-page template with the following
parts:
- Customer Summary
- Storyboard
- Requirements
- Partner teams
The following sections walk through each section and give an
example from one of our BVPs, [[http://windows/hyper-v/initiatives/Value Propositions/DynamicDatacenter-ValueProp.docx][Resource-Smart Virtualization
Infrastructure]] (also called /Dynamic Datacenter/).
*** Customer Summary
The /customer summary/ section is a one-sentence description of
the customer value proposition, written from the customer's point
of view. Each customer summary starts with the phrase, /I want.../
The purpose of this section is to make sure we can give a concise
description of what we expect the customer to accomplish.
#+BEGIN_QUOTE
/Example:/
I want to add or remove computing resources to company owned
virtualization infrastructure automatically, on-demand in
response to rapidly changing business needs without any loss of
business availability.
#+END_QUOTE
*** Storyboard
To help people understand the customer scenario, the /storyboard/
section walks through the steps the customer would take to get the
new value from Windows 8.
#+BEGIN_QUOTE
/Example:/
Comsco warehouse IT provides access to multitudes of different
workloads including database servers, LOB applications, and
homegrown three-tier distributed applications spread across two
sites. Tim, administrator at Comsco IT, wants to see VM life cycle
management (create, deploy, service, move and destroy) utilizing
their existing tools and want it to be more efficient process than
managing physical servers. Tim wants Microsoft software to
automatically create new VM on server from a pool of physical
servers and deploy workload in the VM when combined criteria of
load balancing and resource utilization he defined are met. While
Tim will continue to monitor real-time usage and Joe, who works in
CIO office, wants historical trending of resource utilization of
CPU, memory, power, storage, network bandwidth, storage bandwidth
and backup bandwidth for selected VMs and workloads across all the
servers. Based on historical trend analysis, Tim receives business
logic requirements from the office of CIO and he defines per VM
multi dimensional policy in Microsoft software to automatically
control resource usage allocation, resource prioritization and
resource move for above resource types. Tim also wants to service
storage hardware without any downtime to running workloads. Tim
wants MS software to freely move workloads between his primary
site and across the town secondary site as needed without any
downtime.
#+END_QUOTE
*** Requirements
This section captures the core requirements for delivering the
customer value. Knowing we would not be able to do everything, we
categorized requirements into those needed for delivering good
value, a better value, and best value. To minimize the
randomization that could come from the bucketing, we identified
the customers who would be satisfied by a given level of value.
#+BEGIN_QUOTE
/Example:/
| Target Level | Customer | Example Requirements |
|--------------+-----------------------------------------+-----------------------------------------------|
| Good | Large/medium enterprises | Storage migration with zero business downtime |
| Better | Early adopters at the Dyanmic I/O model | VM migration for load balancing |
| Best | Hosters | Chargeback infrastructure |
#+END_QUOTE
*** Partner teams
Because BVPs describe end-to-end value, none can be delivered just
from the Hyper-V team. This section notes the partner teams we
would need to reach out to.
#+BEGIN_QUOTE
/Example:/
SCVMM, Failover clustering, Kernel, Intel & AMD
#+END_QUOTE
** BVP Ranking
Working with Mike Neil's team, the Hyper-V trio and PM leads ranked
the BVPs based on the information we'd gathered through CFD
sessions and on the importance of competing with VMWare. The
consensus opinion is stored in a spreadsheet [[http://windows/hyper-v/initiatives/Value Propositions/ValueProposition-BucketTemplate-Master.xlsx][here]].
For each BVP, we also identified the target value level -- would we
aim for good value, better value, or best value?
Here's our ranked BVP list.
| Value Proposition | Customer Statement | Target Bucket |
|----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------|
| Resource-Smart Virtualization Infrastructure | I want to add or remove computing resources to company owned virtualization infrastructure automatically, on-demand in response to rapidly changing business needs without any loss of business availability. | Best |
| Server High Availability | I want to ensure that my server applications are highly available. | Better |
| Server Disaster Recovery | I want to ensure my business can quickly resume operations in the event of a disaster. | Better |
| Platform Extensibility | I want a rich ecosystem so I'm not locked into a single vendor for storage, networking, etc. | Better |
| Hosting | I need to be able to deploy thousands of physical servers into one or more farms dedicated for hosting. Provisioning of virtual machines must integrate fully into my back end network topology. Virtual machines must have strong network isolation. I must be able to monitor, change, charge for and throttle usage dynamically. I must be able to move virtual machines to another server in my farm with little or no downtime. | Better |
| Scale Up | I want to get the maximum utilization from my hardware investment. | Better |
| VDI | I want to control cost by deploying thin desktops and letting employees connect to a completely virtualized desktop. | Better |
| Cloud Integration | I want to be able to dynamically enable movement of workloads between on premise and off premise without changing the operational or application model. | Better |
| Security | I want to enhance the security of my system by making it more difficult for malicious programs to attack my operating system core. | Good |
| Deployment | I want to increase efficiency in managing my datacenter & desktop infrastructure. | Better |
| Green IT | I want to increase energy efficiency in my datacenter infrastructure. | Good |
| Server test/dev | I want to quickly and easily create and test server applications. | Good |
| Appliance Development Model | I want to reduce development costs by shipping a server application in a pre-configured VM. | Good |
| Application Compatibility | I want users to have access to old applications even when I upgrade their desktop operating systems. | Cut |
| Client test/dev | I want to quickly and easily create and test desktop applications | Cut |
| Integration Testing | I want to quickly and easily test new applications and updates before deploying them | Cut |
| Employee-owned hardware | I want to let employees use their own hardware to run corporate applications and connect to the corporate network in a secure way. | Cut |
* DONE One-Page Specs
SCHEDULED: <2009-12-07 Mon> CLOSED: [2009-12-07 Mon 16:39]
CLOCK: [2009-12-07 Mon 16:26]--[2009-12-07 Mon 16:39] => 0:13
Armed with the prioritized list of customer value propositions to
consider for Windows 8, we started work on the next level of detail:
What features would we need to implement to deliver the value
proposition? Two main tasks refined our thinking in this
area. First, we brainstormed all of the features required to deliver
the target level of value in the BVP. Then, to reduce ambiguity, we
wrote a /one page spec/ for each feature. What exactly does
/cross-cluster live migration/ mean? The one-page spec tells
you. The goal of the one page spec was to capture just enough
information that a developer could estimate how expensive the
feature would be to implement. Our one-page spec library is [[http://windows/hyper-v/w8/Specs/Forms/AllItems.aspx][here]].
#+BEGIN_QUOTE
/Example: Cross-cluster live migration/
Key customer scenario: An enterprise is building large scale Hyper-V
based infrastructure to run vast majority of server workloads with
High-Availability is a requirement. Customer builds multiple
clusters for one or more of the following business needs:
# NOTE, for formatting reasons, don't fill the following.
- To keep cluster size to be manageable based on preconceived perception of node failure time is linearly proportional to cluster size,
- Due to increased business need they need to build new cluster once maximum supported cluster size is reached,
- There are departmental clusters and temporarily there is a need to use extra capacity of a cluster when one cluster experiences capacity peaks.
Customer would like ability to live migrate, quick migrate or move
VMs from one cluster to other cluster for above mentioned needs.
The goal is to provide more flexibility in VM mobility space without
cluster as a boundary. Hyper-V needs to perform two operations in a
transaction:
- Live migrate VM from one cluster node to destination cluster node.
- Live migrate VM’s storage from one cluster’s shared storage to another cluster’s shared storage.
If any of the above fails, VM must continue to run on the source
node.
A user should be able to orchestrate live migration through Hyper-V
manager, Failover cluster UI, WMI or Powershell.
Live migration should perform necessary checks to ensure live
migration requirements are met. Some of the examples in addition to
other migration checks are, performing estimation of time to migrate
VM, access to the VM storage and same IP network on destination to
ensure VM will be able to migrate successfully without dropping a
TCP connection. If Hyper-V cannot reliably guaranty retaining TCP
connection live migration should fail and must ensure VM continues
to run on source node.
Administrator should be able to set cluster wide, Hyper-V wide or
per VM policies around allowing or denying live migrating one or
more VMs from one cluster to any particular cluster or any other
cluster.
User experience and workflow of orchestrating live migration within
a cluster or across the cluster site should be the same.
#+END_QUOTE
* DONE Feature SWAGS
CLOSED: [2009-12-09 Wed 08:57]
CLOCK: [2009-12-09 Wed 08:46]--[2009-12-09 Wed 08:57] => 0:11
SCHEDULED: <2009-12-07 Mon>
Using the one-page specs, the dev team estimated the dev time it
would take to implement each feature identified to deliver on the
business value propositions. The estimates are kept in this
[[http://windows/hyper-v/w8/BVP/BVP%20Feature%20Expansion.xlsx][spreadsheet]]. The estimaes are fine-grained. To stretch an analogy,
instead of t-shirt sizes, we've got estimates of the yards of thread
required to make the t-shirt. For each feature we identified in the
BVP process, the dev team estimated how to break apart the work and
estimated the number of weeks of senior, mid-level, and junior dev
time it would take to implement the feature.
The key conclusion from the exercise: Our eyes are *way* bigger than
our wallets. In the BVP process, we identified about five times as
much work as we will be able to deliver in Windows 8.
* DONE Moving From Pre-Planning to Planning
CLOSED: [2009-12-09 Wed 15:20]
CLOCK: [2009-12-09 Wed 09:56]--[2009-12-09 Wed 10:01] => 0:05
CLOCK: [2009-12-09 Wed 09:00]--[2009-12-09 Wed 09:01] => 0:01
Pre-planning identified a significant amount of work we /could/ do
in Windows 8. Our challenge in planning has been to identify the 20%
of the work on our list that best aligns with the overall Windows
vision, so we can commit to this as work we /will/ do for Windows 8.
The business value propositions we defined in pre-planning lined up
well with planning themes & subthemes. As we moved from pre-planning
to planning, we narrowed down the list of BVPs that we focused on,
and we worked through the established theme & subtheme
planning. Through the Windows planning process, we have been able to
work with our partner teams to find alignment on priorities.
The following table shows how we mapped our BVPs to planning themes
for the planning process.
| BVP | Planning Theme (Subtheme) |
|--------------------------------------------------------------------------+----------------------------------------------------------------------------------------|
| Resource-Smart Virtualization Infrastructure, Hosting, Cloud Integration | Infrastructure Scaled for SMB, Enterprise, & Service Providers (Hosted Private Clouds) |
| Server High Availability | Continuous Availability (Contiuous Availability) |
| Server Disaster Recovery | Continuous Availability (Business Continuity) |
| Platform Extensibility | Big Bet: Scale for Datacenters |
| Scale Up, Green IT | Infrastructure Scaled... (Leverage the Hardware Ecosystem) |
| VDI | Work Anywhere (Centralized Desktops) |
| Deployment | Management (Solution Deployment) |
| Server test/dev, Client test/dev | Streamline the developer experience *or* Desktop for enthusiasts |
| Appliance Development Model | Infrastructure Scaled... (Virtual Appliance for Partners) |
* TODO Conclusion
Because of our pre-planning work, we've had good alignment between
COSD (and now Windows Core) and Windows Server on overall Hyper-V
priorities and directions. The work on estimating feature costs has
enabled us to set realistic expectations on the scope of work we can
deliver in Windows 8. Taken together, our pre-planning work should
have made Hyper-V a more predictable and transparent partner team to
work with in the planning process.
ruby-org-0.8.0/spec/data/remember.org 0000664 0000000 0000000 00000004036 12105711076 0017442 0 ustar 00root root 0000000 0000000 * New Ideas
** YAML header in Webby
Make sure you don't have TABS here. Best practice: Configure your
editor to use spaces instaed of tabs, and if you can see whitespace,
even better.
In emacs, set indent-tabs-mode to NIL.
** Ruby Gems behind Proxy
Set the following environment variable:
So, I added a User Variable for my account called http_proxy with
the value of http://:8080, rebooted, ran plan
old vanillia gem install rails –include-dependencies, and magically,
it worked
** Hyper-V technical info
http://technet.microsoft.com/en-us/dd565807.aspx
** VirtualBox
Virtualization software from Sun. Looks like it might be more for
dev/test. I'm surprised this hasn't popped at
all. http://www.virtualbox.org/. Backed by Sun.
** Interesting LaTeX article
http://nitens.org/taraborelli/latex -- on the virtues of LaTeX
** XEmacs / Emacs internals
Looks like an interesting resource if I want to learn how Emacs works.
http://www.xemacs.org/Documentation/21.5/html/internals_9.html#SEC19
** MikTeX
Get it here: http://www.miktex.org/portable/
** Orgmode publishing tutorial
[[http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.php][Publishing Org-mode files to HTML]]
** Git and Live Mesh
This is really helpful:
http://whereslou.com/2009/06/04/using-live-mesh-and-git-the-best-of-both-worlds
** VDI deployment stats
Key takeaways:
- 74% are using VDI in production or pilot ... but 45% of those using have less than 100 users
- Upward of 55% of the DAC members [project] they will have up to 50% of their users using VDI in 3 years (~1/2 of those will have > 50%)
- No real surprises on the reasons / benefits etc
- Interestingly ... even if TS supported all client apps / supported user-install apps - 100% of the DAC preferred VDI over TS
- Most companies said a portion of their users would have VDI as the primary replacement desktop (60% < 20% of users, 32% 21-50% of users)
** Hyper-V Scheduler Information
http://msdn.microsoft.com/en-us/library/bb969782.aspx
ruby-org-0.8.0/spec/data/tables.org 0000664 0000000 0000000 00000000154 12105711076 0017113 0 ustar 00root root 0000000 0000000 * a table with hline at the beginning
|-----+-----|
| foo | bar |
|-----+-----|
| 1 | 2 |
* not a table
ruby-org-0.8.0/spec/headline_spec.rb 0000664 0000000 0000000 00000003452 12105711076 0017333 0 ustar 00root root 0000000 0000000 require 'spec_helper'
describe Orgmode::Headline do
it "should recognize headlines that start with asterisks" do
Orgmode::Headline.headline?("*** test\n").should_not be_nil
end
it "should reject headlines without headlines at the start" do
Orgmode::Headline.headline?(" nope!").should be_nil
Orgmode::Headline.headline?(" tricked you!!!***").should be_nil
end
it "should reject improper initialization" do
lambda { Orgmode::Headline.new " tricked**" }.should raise_error
end
it "should properly determine headline level" do
samples = ["* one", "** two", "*** three", "**** four"]
expected = 1
samples.each do |sample|
h = Orgmode::Headline.new sample
h.level.should eql(expected)
expected += 1
end
end
it "should properly determine headline level with offset" do
h = Orgmode::Headline.new("* one", nil, 1)
h.level.should eql(2)
end
it "should find simple headline text" do
h = Orgmode::Headline.new "*** sample"
h.headline_text.should eql("sample")
end
it "should understand tags" do
h = Orgmode::Headline.new "*** sample :tag:tag2:\n"
h.headline_text.should eql("sample")
h.should have(2).tags
h.tags[0].should eql("tag")
h.tags[1].should eql("tag2")
end
it "should understand a single tag" do
h = Orgmode::Headline.new "*** sample :tag:\n"
h.headline_text.should eql("sample")
h.should have(1).tags
h.tags[0].should eql("tag")
end
it "should understand keywords" do
h = Orgmode::Headline.new "*** TODO Feed cat :home:"
h.headline_text.should eql("Feed cat")
h.keyword.should eql("TODO")
end
it "should recognize headlines marked as COMMENT" do
h = Orgmode::Headline.new "* COMMENT This headline is a comment"
h.comment_headline?.should_not be_nil
end
end
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/ 0000775 0000000 0000000 00000000000 12105711076 0023510 5 ustar 00root root 0000000 0000000 ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-coderay.html 0000664 0000000 0000000 00000023717 12105711076 0030511 0 ustar 00root root 0000000 0000000 advanced-code-coderay.org
Turns out there’s more way to do code than just BEGIN_EXAMPLE.
1 Inline examples
This should work:
fixed width? how does this work?
...........
............
.
. . . .
. ..
....... .....
. .
....
Two ASCII blobs.
2 BEGIN_SRC
And this:
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
Now let’s test case-insensitive code blocks.
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
Even if no language is set, it is still wrapped in code tags but class is empty.
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
3 It should be possible to write a colon at the beginning of an example
I really love to write about
:symbols. They sure are the
best things in the world!
{
:one => 1,
:two => 2
}
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
4 Code syntax highlight with Coderay
4.1 No language selected
Nothing to see here
4.2 CSS example
* {
/* apply a natural box layout model to all elements */
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
4.3 HTML example
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
4.4 Ruby example
class Post << ActiveRecord::Base
def print_title
puts "#{self.title}"
end
end
4.5 Python example
import mapnik
m = mapnik.Map(600, 800)
m.background = Map.Color('steelblue')
4.6 Javascript example
exports = this;
(function($){
var Posts = {};
Posts.index = function(){
// TODO
};
})(jQuery);
4.7 JSON example
{ name: "Waldemar"
, surname: "Quevedo"
}
4.8 PHP example
echo "Hello";
phpinfo();
var_dump(some_var);
4.9 Elisp example
(defun hello()
(interactive)
(message "hello"))
4.10 Not supported language example
!+!+++!++!++!++!+
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-coderay.org 0000664 0000000 0000000 00000007524 12105711076 0030332 0 ustar 00root root 0000000 0000000 #+TITLE: advanced-code-coderay.org
#+AUTHOR: Brian Dewey
#+EMAIL: bdewey@gmail.com
#+DATE: 2009-12-30 Wed
#+DESCRIPTION: More types of code support
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
Turns out there's more way to do code than just BEGIN_EXAMPLE.
* Inline examples
This should work:
: fixed width? how does this work?
: ...........
: ............
: .
: . . . .
: . ..
: ....... .....
: . .
: ....
Two ASCII blobs.
* BEGIN_SRC
:PROPERTIES:
:ARCHIVE_TIME: 2009-12-26 Sat 22:16
:ARCHIVE_FILE: ~/brians-brain/content/projects/orgmode_parser.org
:ARCHIVE_OLPATH: <%= @page.title %>/Future Development
:ARCHIVE_CATEGORY: orgmode_parser
:ARCHIVE_TODO: DONE
:END:
And this:
#+BEGIN_SRC ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+END_SRC
Now let's test case-insensitive code blocks.
#+begin_src ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+end_src
#+begin_src clojure
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
#+end_src
Even if no language is set, it is still wrapped in code tags but class is empty.
#+BEGIN_SRC
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
#+END_SRC
* It should be possible to write a colon at the beginning of an example
#+BEGIN_QUOTE
I really love to write about
:symbols. They sure are the
best things in the world!
#+END_QUOTE
#+BEGIN_SRC ruby
{
:one => 1,
:two => 2
}
#+END_SRC
#+BEGIN_SRC clojure
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
#+END_SRC
* Code syntax highlight with Coderay
** No language selected
#+BEGIN_SRC
Nothing to see here
#+END_SRC
** CSS example
#+BEGIN_SRC css
* {
/* apply a natural box layout model to all elements */
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
#+END_SRC
** HTML example
#+BEGIN_SRC html
Hello
Hello
#+END_SRC
** Ruby example
#+BEGIN_SRC ruby
class Post << ActiveRecord::Base
def print_title
puts "#{self.title}"
end
end
#+END_SRC
** Python example
#+BEGIN_SRC python
import mapnik
m = mapnik.Map(600, 800)
m.background = Map.Color('steelblue')
#+END_SRC
** Javascript example
#+BEGIN_SRC javascript
exports = this;
(function($){
var Posts = {};
Posts.index = function(){
// TODO
};
})(jQuery);
#+END_SRC
** JSON example
#+BEGIN_SRC json
{ name: "Waldemar"
, surname: "Quevedo"
}
#+END_SRC
** PHP example
#+BEGIN_SRC php
echo "Hello";
phpinfo();
var_dump(some_var);
#+END_SRC
** Elisp example
#+BEGIN_SRC emacs-lisp
(defun hello()
(interactive)
(message "hello"))
#+END_SRC
** Not supported language example
#+BEGIN_SRC notsupported
!+!+++!++!++!++!+
#+END_SRC
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-no-color.html 0000664 0000000 0000000 00000004240 12105711076 0030601 0 ustar 00root root 0000000 0000000 advanced-code.org
Turns out there’s more way to do code than just BEGIN_EXAMPLE.
1 Inline examples
This should work:
fixed width? how does this work?
...........
............
.
. . . .
. ..
....... .....
. .
....
Two ASCII blobs.
2 BEGIN_SRC
And this:
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
Now let’s test case-insensitive code blocks.
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
Even if no language is set, it is still wrapped in code tags but class is empty.
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
3 It should be possible to write a colon at the beginning of an example
I really love to write about
:symbols. They sure are the
best things in the world!
{
:one => 1,
:two => 2
}
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-no-color.org 0000664 0000000 0000000 00000005173 12105711076 0030432 0 ustar 00root root 0000000 0000000 #+TITLE: advanced-code.org
#+AUTHOR: Brian Dewey
#+EMAIL: bdewey@gmail.com
#+DATE: 2009-12-30 Wed
#+DESCRIPTION: More types of code support
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
Turns out there's more way to do code than just BEGIN_EXAMPLE.
* Inline examples
This should work:
: fixed width? how does this work?
: ...........
: ............
: .
: . . . .
: . ..
: ....... .....
: . .
: ....
Two ASCII blobs.
* BEGIN_SRC
:PROPERTIES:
:ARCHIVE_TIME: 2009-12-26 Sat 22:16
:ARCHIVE_FILE: ~/brians-brain/content/projects/orgmode_parser.org
:ARCHIVE_OLPATH: <%= @page.title %>/Future Development
:ARCHIVE_CATEGORY: orgmode_parser
:ARCHIVE_TODO: DONE
:END:
And this:
#+BEGIN_SRC ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+END_SRC
Now let's test case-insensitive code blocks.
#+begin_src ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+end_src
#+begin_src clojure
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
#+end_src
Even if no language is set, it is still wrapped in code tags but class is empty.
#+BEGIN_SRC
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
#+END_SRC
* It should be possible to write a colon at the beginning of an example
#+BEGIN_QUOTE
I really love to write about
:symbols. They sure are the
best things in the world!
#+END_QUOTE
#+BEGIN_SRC ruby
{
:one => 1,
:two => 2
}
#+END_SRC
#+BEGIN_SRC clojure
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
#+END_SRC
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-pygments.html 0000664 0000000 0000000 00000024576 12105711076 0030735 0 ustar 00root root 0000000 0000000 advanced-code.org
Turns out there’s more way to do code than just BEGIN_EXAMPLE.
1 Inline examples
This should work:
fixed width? how does this work?
...........
............
.
. . . .
. ..
....... .....
. .
....
Two ASCII blobs.
2 BEGIN_SRC
And this:
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
Now let’s test case-insensitive code blocks.
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
Even if no language is set, it is still wrapped in code tags but class is empty.
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
3 It should be possible to write a colon at the beginning of an example
I really love to write about
:symbols. They sure are the
best things in the world!
{
:one => 1,
:two => 2
}
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
4 Code syntax highlight with Pygments
4.1 No language selected
<script>alert('hello world')</script>
4.2 CSS example
* {
/* apply a natural box layout model to all elements */
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
4.3 HTML example
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
4.4 Ruby example
class Post << ActiveRecord::Base
def print_title
puts "#{self.title}"
end
end
4.5 Python example
import mapnik
m = mapnik.Map(600, 800)
m.background = Map.Color('steelblue')
4.6 Javascript example
exports = this;
(function($){
var Posts = {};
Posts.index = function(){
// TODO
};
})(jQuery);
4.7 JSON example
{ name: "Waldemar"
, surname: "Quevedo"
}
4.8 PHP example
echo "Hello";
phpinfo();
var_dump(some_var);
4.9 Elisp example
(defun hello()
(interactive)
(message "hello"))
4.10 Not supported language example
!+!+++!++!++!++!+
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/advanced-code-pygments.org 0000664 0000000 0000000 00000007547 12105711076 0030557 0 ustar 00root root 0000000 0000000 #+TITLE: advanced-code.org
#+AUTHOR: Brian Dewey
#+EMAIL: bdewey@gmail.com
#+DATE: 2009-12-30 Wed
#+DESCRIPTION: More types of code support
#+KEYWORDS:
#+LANGUAGE: en
#+OPTIONS: H:3 num:t toc:nil \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
#+OPTIONS: TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
#+EXPORT_SELECT_TAGS: export
#+EXPORT_EXCLUDE_TAGS: noexport
#+LINK_UP:
#+LINK_HOME:
Turns out there's more way to do code than just BEGIN_EXAMPLE.
* Inline examples
This should work:
: fixed width? how does this work?
: ...........
: ............
: .
: . . . .
: . ..
: ....... .....
: . .
: ....
Two ASCII blobs.
* BEGIN_SRC
:PROPERTIES:
:ARCHIVE_TIME: 2009-12-26 Sat 22:16
:ARCHIVE_FILE: ~/brians-brain/content/projects/orgmode_parser.org
:ARCHIVE_OLPATH: <%= @page.title %>/Future Development
:ARCHIVE_CATEGORY: orgmode_parser
:ARCHIVE_TODO: DONE
:END:
And this:
#+BEGIN_SRC ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+END_SRC
Now let's test case-insensitive code blocks.
#+begin_src ruby
# Finds all emphasis matches in a string.
# Supply a block that will get the marker and body as parameters.
def match_all(str)
str.scan(@org_emphasis_regexp) do |match|
yield $2, $3
end
end
#+end_src
#+begin_src clojure
(def fib-seq
(concat
[0 1]
((fn rfib [a b]
(lazy-cons (+ a b) (rfib b (+ a b)))) 0 1)))
user> (take 20 fib-seq)
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181)
#+end_src
Even if no language is set, it is still wrapped in code tags but class is empty.
#+BEGIN_SRC
echo 'Defaults env_keeps="http_proxy https_proxy ftp_proxy"' | sudo tee -a /etc/sudoers
#+END_SRC
* It should be possible to write a colon at the beginning of an example
#+BEGIN_QUOTE
I really love to write about
:symbols. They sure are the
best things in the world!
#+END_QUOTE
#+BEGIN_SRC ruby
{
:one => 1,
:two => 2
}
#+END_SRC
#+BEGIN_SRC clojure
(defproject helloworld "0.1"
:dependencies [[org.clojure/clojure
"1.1.0-master-SNAPSHOT"]
[org.clojure/clojure-contrib
"1.0-SNAPSHOT"]]
:main helloworld)
#+END_SRC
* Code syntax highlight with Pygments
** No language selected
#+BEGIN_SRC
#+END_SRC
** CSS example
#+BEGIN_SRC css
* {
/* apply a natural box layout model to all elements */
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
#+END_SRC
** HTML example
#+BEGIN_SRC html
Hello
Hello
#+END_SRC
** Ruby example
#+BEGIN_SRC ruby
class Post << ActiveRecord::Base
def print_title
puts "#{self.title}"
end
end
#+END_SRC
** Python example
#+BEGIN_SRC python
import mapnik
m = mapnik.Map(600, 800)
m.background = Map.Color('steelblue')
#+END_SRC
** Javascript example
#+BEGIN_SRC javascript
exports = this;
(function($){
var Posts = {};
Posts.index = function(){
// TODO
};
})(jQuery);
#+END_SRC
** JSON example
#+BEGIN_SRC json
{ name: "Waldemar"
, surname: "Quevedo"
}
#+END_SRC
** PHP example
#+BEGIN_SRC php
echo "Hello";
phpinfo();
var_dump(some_var);
#+END_SRC
** Elisp example
#+BEGIN_SRC emacs-lisp
(defun hello()
(interactive)
(message "hello"))
#+END_SRC
** Not supported language example
#+BEGIN_SRC notsupported
!+!+++!++!++!++!+
#+END_SRC
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/code-coderay.html 0000664 0000000 0000000 00000001636 12105711076 0026742 0 ustar 00root root 0000000 0000000 Simple Code Syntax highlighting test
class Coderay
class << self
def colorize
# Do colorizing stuff here
heredoc = <<EOF
Some text yay!!!
EOF
end
end
end
ruby-org-0.8.0/spec/html_code_syntax_highlight_examples/code-coderay.org 0000664 0000000 0000000 00000000330 12105711076 0026553 0 ustar 00root root 0000000 0000000 * Simple Code Syntax highlighting test
#+BEGIN_SRC ruby
class Coderay
class << self
def colorize
# Do colorizing stuff here
heredoc = <