File: textile_output_buffer.rb

package info (click to toggle)
ruby-org 0.9.12-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,852 kB
  • sloc: ruby: 3,044; lisp: 50; makefile: 4
file content (154 lines) | stat: -rw-r--r-- 4,435 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
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)
      super(mode, indent)
      @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