Skip to content

Commit

Permalink
Parse and store in-buffer settings. Still need to handle OPTIONS hash.
Browse files Browse the repository at this point in the history
  • Loading branch information
bdewey committed Dec 29, 2009
1 parent 3616f28 commit 1a87985
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 0 deletions.
4 changes: 4 additions & 0 deletions History.txt
@@ -1,3 +1,7 @@
== X.X.X / 2009-12-XX

* Parse in-buffer settings.

== 0.4.2 / 2009-12-29

* Got rid of the extraneous newline at the start of code blocks.
Expand Down
21 changes: 21 additions & 0 deletions lib/org-ruby/line.rb
Expand Up @@ -108,6 +108,27 @@ def block_type
$2 if @line =~ BlockRegexp
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 paragraph_type
return :blank if blank?
Expand Down
9 changes: 9 additions & 0 deletions lib/org-ruby/parser.rb
Expand Up @@ -17,6 +17,10 @@ class Parser

# 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

# I can construct a parser object either with an array of lines
# or with a single string that I will split along \n boundaries.
Expand All @@ -32,6 +36,7 @@ def initialize(lines)
@headlines = Array.new
@current_headline = nil
@header_lines = []
@in_buffer_settings = { }
mode = :normal
@lines.each do |line|
case mode
Expand All @@ -42,6 +47,10 @@ def initialize(lines)
@headlines << @current_headline
else
line = Line.new line
# If there is a setting on this line, remember it.
line.in_buffer_setting? do |key, value|
@in_buffer_settings[key] = value
end
mode = :code if line.begin_block? and line.block_type == "EXAMPLE"
if (@current_headline) then
@current_headline.body_lines << line
Expand Down
113 changes: 113 additions & 0 deletions spec/data/freeform-example.org
@@ -0,0 +1,113 @@
#+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.
35 changes: 35 additions & 0 deletions spec/line_spec.rb
Expand Up @@ -106,4 +106,39 @@
l.paragraph_type.should eql(value)
end
end

it "should parse in-buffer settings" do
cases = {
"#+ARCHIVE: %s_done" => { :key => "ARCHIVE", :value => "%s_done" },
"#+CATEGORY: foo" => { :key => "CATEGORY", :value => "foo"},
"#+BEGIN_EXAMPLE:" => { :key => "BEGIN_EXAMPLE", :value => "" },
"#+A:" => { :key => "A", :value => "" } # Boundary: Smallest keyword is one letter
}
cases.each_pair do |key, value|
l = Orgmode::Line.new key
l.in_buffer_setting?.should be_true
called = nil
l.in_buffer_setting? do |k, v|
k.should eql(value[:key])
v.should eql(value[:value])
called = true
end
called.should be_true
end
end

it "should reject ill-formed settings" do
cases = [
"##+ARCHIVE: blah",
"#CATEGORY: foo",
"",
"\n",
" #+BEGIN_EXAMPLE:\n"
]

cases.each do |c|
l = Orgmode::Line.new c
l.in_buffer_setting?.should be_nil
end
end
end
13 changes: 13 additions & 0 deletions spec/parser_spec.rb
Expand Up @@ -42,6 +42,19 @@
parser.should have(19).header_lines
end

it "should load in-buffer settings" do
parser = Orgmode::Parser.load(FreeformFile)
parser.should have(13).in_buffer_settings
parser.in_buffer_settings["TITLE"].should eql("Freeform")
parser.in_buffer_settings["EMAIL"].should eql("bdewey@gmail.com")
parser.in_buffer_settings["LANGUAGE"].should eql("en")
end

it "should skip in-buffer settings inside EXAMPLE blocks" do
parser = Orgmode::Parser.load(FreeformExampleFile)
parser.should have(0).in_buffer_settings
end

it "should return a textile string" do
parser = Orgmode::Parser.load(FreeformFile)
parser.to_textile.should be_kind_of(String)
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Expand Up @@ -5,6 +5,7 @@

RememberFile = File.join(File.dirname(__FILE__), %w[data remember.org])
FreeformFile = File.join(File.dirname(__FILE__), %w[data freeform.org])
FreeformExampleFile = File.join(File.dirname(__FILE__), %w[data freeform-example.org])


Spec::Runner.configure do |config|
Expand Down

0 comments on commit 1a87985

Please sign in to comment.