aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rdoc/parser/changelog.rb
blob: 98174406ed7b273f78dacec83dc2ae658afb8889 (plain)
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
require 'time'

class RDoc::Parser::ChangeLog < RDoc::Parser

  include RDoc::Parser::Text

  parse_files_matching(/(\/|\\|\A)ChangeLog[^\/\\]*\z/)

  def create_document groups
    doc = RDoc::Markup::Document.new
    doc.file = @top_level

    doc << RDoc::Markup::Heading.new(1, File.basename(@file_name))
    doc << RDoc::Markup::BlankLine.new

    groups.each do |day, entries|
      doc << RDoc::Markup::Heading.new(2, day)
      doc << RDoc::Markup::BlankLine.new

      doc.concat create_entries entries
    end

    doc
  end

  def create_entries entries
    out = []

    entries.each do |entry, items|
      out << RDoc::Markup::Heading.new(3, entry)
      out << RDoc::Markup::BlankLine.new

      out << create_items(items)
    end

    out
  end

  def create_items items
    list = RDoc::Markup::List.new :NOTE

    items.each do |item|
      title, body = item.split /:\s*/, 2
      paragraph = RDoc::Markup::Paragraph.new body
      list_item = RDoc::Markup::ListItem.new title, paragraph
      list << list_item
    end

    list
  end

  def group_entries entries
    entries.group_by do |title, body|
      Time.parse(title).strftime "%Y-%m-%d"
    end
  end

  def parse_entries
    entries = {}
    entry_name = nil
    entry_body = []

    @content.each_line do |line|
      case line
      when /^\w.*/ then
        entries[entry_name] = entry_body if entry_name

        entry_name = $&

        begin
          Time.parse entry_name
        rescue ArgumentError
          entry_name = nil
        end

        entry_body = []
      when /^(\t| {8})\*\s*(.*)/ then
        entry_body << $2
      when /^(\t| {8})\s*(.*)/ then
        continuation = $2
        next unless last = entry_body.last

        if last =~ /\s\z/ then
          last << continuation
        else
          last << ' ' << continuation
        end
      end
    end

    entries[entry_name] = entry_body if entry_name

    entries.delete nil

    entries
  end

  def scan
    entries = parse_entries
    grouped_entries = group_entries entries

    doc = create_document grouped_entries

    @top_level.comment = doc

    @top_level
  end

end