elisp2any 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/LICENSE.txt +674 -202
  4. data/README.md +15 -5
  5. data/Rakefile +1 -46
  6. data/exe/elisp2any +4 -5
  7. data/lib/elisp/comment.rb +93 -0
  8. data/lib/elisp/parser.rb +188 -0
  9. data/lib/elisp.rb +142 -0
  10. data/lib/elisp2any/aside.rb +23 -0
  11. data/lib/elisp2any/blanklines.rb +7 -4
  12. data/lib/elisp2any/code.rb +26 -12
  13. data/lib/elisp2any/codeblock.rb +56 -0
  14. data/lib/elisp2any/comment.rb +3 -1
  15. data/lib/elisp2any/commentary.rb +10 -7
  16. data/lib/elisp2any/expression.rb +81 -5
  17. data/lib/elisp2any/footer_line.rb +28 -0
  18. data/lib/elisp2any/header_line.rb +40 -7
  19. data/lib/elisp2any/heading.rb +21 -4
  20. data/lib/elisp2any/html_renderer/index.html.erb +16 -16
  21. data/lib/elisp2any/html_renderer.erb +22 -0
  22. data/lib/elisp2any/html_renderer.rb +98 -12
  23. data/lib/elisp2any/inline_code.rb +1 -0
  24. data/lib/elisp2any/line.rb +5 -3
  25. data/lib/elisp2any/paragraph.rb +3 -4
  26. data/lib/elisp2any/section.rb +32 -8
  27. data/lib/elisp2any/text.rb +33 -0
  28. data/lib/elisp2any/version.rb +2 -1
  29. data/lib/elisp2any.rb +19 -1
  30. metadata +14 -80
  31. data/.document +0 -4
  32. data/.envrc +0 -3
  33. data/.rdoc_options +0 -2
  34. data/.rubocop.yml +0 -11
  35. data/lib/elisp2any/asciidoc_renderer/index.adoc.erb +0 -15
  36. data/lib/elisp2any/asciidoc_renderer.rb +0 -57
  37. data/lib/elisp2any/code_block.rb +0 -16
  38. data/lib/elisp2any/file.rb +0 -47
  39. data/lib/elisp2any/filename.rb +0 -14
  40. data/lib/elisp2any/header_line_variable_assignment.rb +0 -27
  41. data/lib/elisp2any/header_line_variables.rb +0 -33
  42. data/lib/elisp2any/node.rb +0 -66
  43. data/lib/elisp2any/top_heading.rb +0 -21
  44. data/lib/elisp2any/tree_sitter_parser.rb +0 -36
  45. data/lib/elisp2any/variable.rb +0 -14
  46. data/manifest.scm +0 -87
  47. data/sig/elisp2any.gen.rbs +0 -112
  48. data/sig/elisp2any.rbs +0 -4
@@ -1,15 +1,13 @@
1
- require "elisp2any/top_heading"
1
+ require "forwardable"
2
2
  require "elisp2any/paragraph"
3
3
  require "elisp2any/blanklines"
4
4
 
5
5
  module Elisp2any
6
6
  class Commentary
7
- attr_reader :paragraphs
8
-
9
7
  def self.scan(scanner)
10
8
  pos = scanner.pos
11
- heading = TopHeading.scan(scanner) or return
12
- unless heading.content == "Commentary:"
9
+ heading = Elisp2any.scan_top_heading(scanner) or return
10
+ unless heading == "Commentary:"
13
11
  scanner.pos = pos
14
12
  return
15
13
  end
@@ -19,11 +17,16 @@ module Elisp2any
19
17
  paragraphs << par
20
18
  Blanklines.scan(scanner) # optional
21
19
  end
22
- new(paragraphs:)
20
+ new(paragraphs)
23
21
  end
24
22
 
25
- def initialize(paragraphs:)
23
+ def initialize(paragraphs)
26
24
  @paragraphs = paragraphs
27
25
  end
26
+
27
+ extend Forwardable # :nodoc:
28
+ def_delegators :@paragraphs, :each, :size
29
+
30
+ include Enumerable
28
31
  end
29
32
  end
@@ -1,13 +1,89 @@
1
+ require "strscan"
2
+
1
3
  module Elisp2any
2
4
  class Expression
3
- attr_reader :content
4
-
5
5
  def self.scan(scanner)
6
- content = scanner.scan(/t\b/) or return
7
- new(content:)
6
+ scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
7
+ if scanner.skip("(")
8
+ exps = []
9
+ while (exp = scan(scanner))
10
+ exps << exp
11
+ spaces = scanner.scan(/[ \n]+/)
12
+ exps << spaces if spaces
13
+ end
14
+ scanner.skip(")") or raise Error, scanner.inspect
15
+ new(exps)
16
+ elsif scanner.skip("'")
17
+ exp = scan(scanner) or raise Error, scanner.inspect
18
+ new({ quoted: exp })
19
+ elsif scanner.skip("\"")
20
+ content = +""
21
+ while !scanner.eos? && !scanner.match?("\\") && !scanner.match?('"')
22
+ content << scanner.getch
23
+ end
24
+ scanner.skip('"') or raise Error, scanner.inspect
25
+ new(content)
26
+ elsif scanner.skip("#'")
27
+ exp = scan(scanner) or raise Error, scanner.inspect
28
+ new({ function: exp })
29
+ else
30
+ name = scanner.scan(/[a-z0-9_?.:-]+/) or return
31
+ new(name.to_sym)
32
+ end
33
+ end
34
+
35
+ def source
36
+ case @content
37
+ in { quoted: }
38
+ "'#{self.class.source(quoted)}"
39
+ in String
40
+ @content
41
+ in { function: }
42
+ "#'#{self.class.source(function)}"
43
+ in Array
44
+ result = +"("
45
+ @content.each { |exp| result << self.class.source(exp) }
46
+ "#{result})"
47
+ in Symbol
48
+ @content.to_s
49
+ end
50
+ end
51
+
52
+ def self.source(arg)
53
+ case arg
54
+ in Symbol
55
+ arg.to_s
56
+ in Array
57
+ result = +"("
58
+ arg.sum { |ele| result << source(ele) }
59
+ "#{result})"
60
+ in Expression
61
+ arg.source
62
+ in String
63
+ arg
64
+ else
65
+ raise arg.inspect
66
+ end
67
+ end
68
+
69
+ def deconstruct_keys(*keys)
70
+ result = {}
71
+ keys => [keys]
72
+ keys.each do |key|
73
+ case key
74
+ in :content
75
+ result[:content] = @content
76
+ else # nop
77
+ end
78
+ end
79
+ result
80
+ end
81
+
82
+ def deconstruct
83
+ [*@content]
8
84
  end
9
85
 
10
- def initialize(content:)
86
+ def initialize(content)
11
87
  @content = content
12
88
  end
13
89
  end
@@ -0,0 +1,28 @@
1
+ require "forwardable"
2
+
3
+ module Elisp2any
4
+ class FooterLine
5
+ def self.scan(scanner)
6
+ scanner = StringScanner.new(scanner) unless scanner.respond_to?(:pos)
7
+ pos = scanner.pos
8
+ heading = Elisp2any.scan_top_heading(scanner) or return
9
+ cscanner = StringScanner.new(heading)
10
+ unless (filename = Elisp2any.scan_filename(cscanner))
11
+ scanner.pos = pos
12
+ return
13
+ end
14
+ unless cscanner.skip(/ ends here\n?/)
15
+ scanner.pos = pos
16
+ return
17
+ end
18
+ new(filename)
19
+ end
20
+
21
+ def initialize(filename)
22
+ @filename = filename
23
+ end
24
+
25
+ extend Forwardable # :nodoc:
26
+ def_delegator :@filename, :==
27
+ end
28
+ end
@@ -1,6 +1,5 @@
1
1
  require "elisp2any/comment"
2
- require "elisp2any/filename"
3
- require "elisp2any/header_line_variables"
2
+ require "elisp2any/expression"
4
3
 
5
4
  module Elisp2any
6
5
  class HeaderLine
@@ -9,12 +8,12 @@ module Elisp2any
9
8
  def self.scan(scanner)
10
9
  scanner = StringScanner.new(scanner) unless scanner.respond_to?(:pos)
11
10
  pos = scanner.pos
12
- unless (heading = TopHeading.scan(scanner))
11
+ unless (heading = Elisp2any.scan_top_heading(scanner))
13
12
  scanner.pos = pos
14
13
  return
15
14
  end
16
- cscanner = StringScanner.new(heading.content)
17
- unless (filename = Filename.scan(cscanner))
15
+ cscanner = StringScanner.new(heading)
16
+ unless (filename = Elisp2any.scan_filename(cscanner))
18
17
  scanner.pos = pos
19
18
  return
20
19
  end
@@ -25,7 +24,7 @@ module Elisp2any
25
24
  description = +""
26
25
  variables = nil
27
26
  until cscanner.eos?
28
- if (variables = HeaderLineVariables.scan(cscanner)) # nop
27
+ if (variables = scan_variables(cscanner)) # nop
29
28
  break
30
29
  else
31
30
  description << cscanner.getch
@@ -35,9 +34,43 @@ module Elisp2any
35
34
  scanner.pos = pos
36
35
  return
37
36
  end
38
- new(filename: filename.content, description:, variables: variables.variables)
37
+ new(filename:, description:, variables:)
39
38
  end
40
39
 
40
+ def self.scan_variables(scanner)
41
+ scanner = StringScanner.new(scanner) unless scanner.respond_to?(:pos)
42
+ scanner.skip(/ *-[*]- +/) or return
43
+ variables = {}
44
+ until scanner.skip(/ +-[*]- */)
45
+ if scanner.eos?
46
+ raise Error, "unexpected end"
47
+ elsif (assign = scan_assignments(scanner))
48
+ variables[assign[:variable]] = assign[:expression]
49
+ elsif scanner.skip(";")
50
+ break
51
+ else
52
+ raise Error, scanner.inspect
53
+ end
54
+ end
55
+ variables
56
+ end
57
+ private_class_method :scan_variables
58
+
59
+ def self.scan_assignments(scanner)
60
+ pos = scanner.pos
61
+ variable = Elisp2any.scan_variable(scanner) or return
62
+ unless scanner.skip(/ *: */)
63
+ scanner.pos = pos
64
+ return
65
+ end
66
+ unless (expression = Expression.scan(scanner))
67
+ scanner.pos = pos
68
+ return
69
+ end
70
+ { variable:, expression: }
71
+ end
72
+ private_class_method :scan_assignments
73
+
41
74
  def initialize(filename:, description:, variables:)
42
75
  @filename = filename
43
76
  @description = description
@@ -3,7 +3,8 @@ require 'forwardable'
3
3
 
4
4
  module Elisp2any
5
5
  class Heading
6
- attr_reader :level, :content
6
+ attr_reader :level
7
+ attr_accessor :content
7
8
 
8
9
  def self.scan(scanner)
9
10
  pos = scanner.pos
@@ -12,10 +13,26 @@ module Elisp2any
12
13
  scanner.pos = pos
13
14
  return
14
15
  end
15
- new(:TODO, comment.colons - 3, comment.content)
16
+ new(:TODO, comment.colons - 3,
17
+ comment.content # do not scan as text at this point
18
+ )
16
19
  end
17
20
 
18
- # TODO
21
+ def deconstruct_keys(*keys)
22
+ result = {}
23
+ keys => [keys]
24
+ keys.each do |key|
25
+ case key
26
+ in :level
27
+ result[:level] = @level
28
+ in :content
29
+ result[:content] = @content
30
+ end
31
+ end
32
+ result
33
+ end
34
+
35
+ # TODO: delete node. Use kwargs.
19
36
  def initialize(node, level, content) # :nodoc:
20
37
  @node = node
21
38
  @level = level
@@ -45,7 +62,7 @@ module Elisp2any
45
62
  @content.match(/\A(?<name>.+?)\.el ends here\Z/)[:name]
46
63
  end
47
64
 
48
- extend Forwardable
65
+ extend Forwardable # :nodoc:
49
66
  def_delegator :@level, :<=>
50
67
  end
51
68
  end
@@ -1,23 +1,23 @@
1
1
  <!doctype html>
2
2
  <html>
3
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title><%= name %></title>
7
- <link rel="stylesheet" href="<%= @css %>">
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title><%= name %></title>
7
+ <link rel="stylesheet" href="<%= @css %>">
8
8
  </head>
9
9
  <body>
10
- <main>
11
- <h1><%= name %></h1>
12
- <p><%= synopsis %></p>
13
- <h2>Commentary</h2>
14
- <% commentary.each do |paragraph| %>
15
- <p><%= render_paragraph(paragraph) %></p>
16
- <% end %>
17
- <h2>Code</h2>
18
- <% code.each do |block| %>
19
- <%= render_block(block, level: 2) %>
20
- <% end %>
21
- </main>
10
+ <main>
11
+ <h1><%= name %></h1>
12
+ <p><%= synopsis %></p>
13
+ <h2>Commentary</h2>
14
+ <% commentary.each do |paragraph| %>
15
+ <p><%= render_paragraph(paragraph) %></p>
16
+ <% end %>
17
+ <h2>Code</h2>
18
+ <% code.each do |block| %>
19
+ <%= render_block(block, level: 2) %>
20
+ <% end %>
21
+ </main>
22
22
  </body>
23
23
  </html>
@@ -0,0 +1,22 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title><%= name %></title>
7
+ <link rel="stylesheet" href="<%= @css %>">
8
+ </head>
9
+ <body>
10
+ <main>
11
+ <h1><%= name %><small> &mdash; <%= synopsis %></small></h1>
12
+ <div style="text-align:right"><%= render(header_line.variables) %></div>
13
+ <% commentary.each do |paragraph| %>
14
+ <%= render(paragraph) %>
15
+ <% end %>
16
+ <h2>Code</h2>
17
+ <% self.code.each do |block| %>
18
+ <%= render(block) %>
19
+ <% end %>
20
+ </main>
21
+ </body>
22
+ </html>
@@ -4,17 +4,66 @@ require 'cgi/util'
4
4
  require_relative 'inline_code'
5
5
  require_relative 'heading'
6
6
  require_relative 'paragraph'
7
- require_relative 'code_block'
7
+ require_relative 'codeblock'
8
8
 
9
9
  module Elisp2any
10
10
  class HTMLRenderer
11
- def initialize(file, css: nil)
11
+ def initialize(file, css: nil, mode:)
12
12
  @file = file
13
13
  @css = css || "https://unpkg.com/mvp.css"
14
+ @mode = mode
14
15
  end
15
16
 
16
- def render
17
- erb_render('index.html.erb')
17
+ # Write gradually?
18
+ def render(node = nil)
19
+ if node
20
+ case node
21
+ in Paragraph
22
+ par = node.sum(+"") { |line| render(line) }
23
+ "<p>#{par}</p>"
24
+ in Line
25
+ begin
26
+ node.sum(+"") { |chunk| render(chunk) }
27
+ rescue => e
28
+ warn node.inspect
29
+ raise e
30
+ end
31
+ in String
32
+ h(node)
33
+ in [] # huh? nop.
34
+ in Section
35
+ result = render(node.heading)
36
+ node.blocks.each { |blo| result << render(blo) }
37
+ node.sections.each { |sec| result << render(sec) }
38
+ result
39
+ in Heading[level:, content:]
40
+ lev = level + 2
41
+ "<h#{lev}>#{render(content)}</h#{lev}>"
42
+ in Codeblock
43
+ "<pre><code>#{h(node.source.chomp)}</code></pre>"
44
+ in { code: }
45
+ "<code>#{h(code)}</code>"
46
+ in Hash
47
+ result = node.sum(+"<dl>") do |key, value|
48
+ "<dt>#{render(key)}</dt><dd>#{render(value)}</dd>"
49
+ end
50
+ "#{result}</dl>"
51
+ in Expression
52
+ "<code>#{h(node.source)}</code>"
53
+ in Text
54
+ node.sum(+"") { |ele| render(ele) }
55
+ else
56
+ raise Error, node.inspect
57
+ end
58
+ else
59
+ case @mode
60
+ in :old
61
+ erb_render('index.html.erb')
62
+ in :new
63
+ source = ::File.read(::File.join(__dir__, 'html_renderer.erb'))
64
+ ERB.new(source).result(binding)
65
+ end
66
+ end
18
67
  end
19
68
 
20
69
  private
@@ -24,26 +73,48 @@ module Elisp2any
24
73
  paragraph.each do |line|
25
74
  line.each do |chunk|
26
75
  case chunk
27
- when InlineCode
76
+ in InlineCode
28
77
  html << "<code>#{h(chunk.content)}</code>"
29
- when String
78
+ in String
30
79
  html << h(chunk)
80
+ in { code: }
81
+ html << "<code>#{h(code)}</code>"
82
+ else
83
+ raise Error, chunk.inspect
31
84
  end
32
85
  end
33
86
  end
34
87
  html
35
88
  end
36
89
 
37
- def render_block(block, level:)
90
+ # TODO: remove level
91
+ def render_block(block, level: nil)
38
92
  html = ''
39
93
  case block
40
94
  when Heading
41
- name = "h#{level + block.level - 1}"
95
+ lev = level
96
+ if level
97
+ lev = level + block.level - 1
98
+ else
99
+ lev = block.level
100
+ end
101
+ name = "h#{lev}"
42
102
  html << "<#{name}>#{h(block.content)}</#{name}>"
43
103
  when Paragraph
44
104
  html << render_paragraph(block)
45
- when CodeBlock
105
+ when Codeblock
46
106
  html << "<pre><code>#{h(block.content)}</code></pre>"
107
+ when [] # huh? nop
108
+ when Section
109
+ render_block(block.heading)
110
+ block.blocks.each do |blo|
111
+ render_block(blo)
112
+ end
113
+ block.sections.each do |sec|
114
+ render_block(sec)
115
+ end
116
+ else
117
+ raise Error, block.inspect
47
118
  end
48
119
  html
49
120
  end
@@ -53,11 +124,26 @@ module Elisp2any
53
124
  ERB.new(source).result(binding)
54
125
  end
55
126
 
56
- def h(string)
57
- CGI.escape_html(string)
127
+ def h(arg)
128
+ case arg
129
+ in String
130
+ CGI.escape_html(arg)
131
+ in Array
132
+ arg.map do |ele|
133
+ h(ele)
134
+ end.join
135
+ in Symbol
136
+ h(arg.to_s)
137
+ in Expression
138
+ h(arg.source)
139
+ in Integer
140
+ h(arg.to_s)
141
+ in Aside
142
+ h(arg.content)
143
+ end
58
144
  end
59
145
 
60
146
  extend Forwardable # :nodoc:
61
- def_delegators :@file, :name, :synopsis, :commentary, :code
147
+ def_delegators :@file, :name, :synopsis, :commentary, :code, :header_line
62
148
  end
63
149
  end
@@ -1,4 +1,5 @@
1
1
  module Elisp2any
2
+ # TODO: delete
2
3
  class InlineCode
3
4
  attr_reader :content
4
5
 
@@ -2,6 +2,7 @@ require 'strscan'
2
2
  require 'forwardable'
3
3
  require_relative 'inline_code'
4
4
  require "elisp2any/comment"
5
+ require "elisp2any/text"
5
6
 
6
7
  module Elisp2any
7
8
  class Line
@@ -15,7 +16,8 @@ module Elisp2any
15
16
  unless comment.padding[0] == " "
16
17
  raise Error, "line comment should have a whitespace padding"
17
18
  end
18
- new(["#{comment.padding[1..]}#{comment.content}"])
19
+ content = "#{comment.padding[1..]}#{comment.content}"
20
+ new(Text.scan(content).to_a)
19
21
  end
20
22
 
21
23
  def initialize(chunks) # :nodoc:
@@ -42,8 +44,8 @@ module Elisp2any
42
44
  new(chunks)
43
45
  end
44
46
 
45
- extend Forwardable
46
- def_delegators :@chunks, :each
47
+ extend Forwardable # :nodoc:
48
+ def_delegators :@chunks, :each, :deconstruct
47
49
 
48
50
  include Enumerable
49
51
  end
@@ -3,8 +3,6 @@ require "elisp2any/line"
3
3
 
4
4
  module Elisp2any
5
5
  class Paragraph
6
- attr_reader :lines
7
-
8
6
  def self.scan(scanner)
9
7
  scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
10
8
  lines = []
@@ -25,12 +23,13 @@ module Elisp2any
25
23
  @end_row = end_row
26
24
  end
27
25
 
26
+ # TODO: delete
28
27
  def code?
29
28
  false
30
29
  end
31
30
 
32
- extend Forwardable
33
- def_delegators :@lines, :empty?, :clear, :<<, :each
31
+ extend Forwardable # :nodoc:
32
+ def_delegators :@lines, :empty?, :clear, :<<, :each, :deconstruct, :size
34
33
  def_delegators :@node, :adjucent?
35
34
 
36
35
  include Enumerable
@@ -1,25 +1,49 @@
1
+ require "forwardable"
1
2
  require "elisp2any/heading"
2
- require "elisp2any/paragraph"
3
3
  require "elisp2any/blanklines"
4
+ require "elisp2any/text"
4
5
 
5
6
  module Elisp2any
6
7
  class Section
7
- attr_reader :heading
8
+ attr_reader :heading,
9
+ # TODO: gather blocks and sections
10
+ :blocks,
11
+ :sections
8
12
 
9
13
  def self.scan(scanner)
10
14
  heading = Heading.scan(scanner) or return
15
+ heading.content = Text.scan(heading.content)
11
16
  Blanklines.scan(scanner) # optional
12
- paragraphs = []
13
- while (par = Paragraph.scan(scanner))
14
- paragraphs << par
17
+ blocks = []
18
+ while (blo = Paragraph.scan(scanner) || Codeblock.scan(scanner))
19
+ blocks << blo
15
20
  Blanklines.scan(scanner) # optional
16
21
  end
17
- new(heading:, paragraphs:)
22
+ pos = scanner.pos
23
+ sections = []
24
+ while (section = scan(scanner))
25
+ if section.level == heading.level + 1
26
+ sections << section
27
+ pos = scanner.pos
28
+ elsif section.level >= heading.level + 2
29
+ raise Error, "too demoted heading"
30
+ else
31
+ scanner.pos = pos
32
+ break
33
+ end
34
+ end
35
+ new(heading:, blocks:, sections:)
18
36
  end
19
37
 
20
- def initialize(heading:, paragraphs:)
38
+ def initialize(heading:, blocks:, sections:)
21
39
  @heading = heading
22
- @paragraphs = paragraphs
40
+ @blocks = blocks
41
+ @sections = sections
23
42
  end
43
+
44
+ alias paragraphs blocks # TODO: delete
45
+
46
+ extend Forwardable # :nodoc:
47
+ def_delegator :@heading, :level
24
48
  end
25
49
  end
@@ -0,0 +1,33 @@
1
+ require "forwardable"
2
+
3
+ module Elisp2any
4
+ class Text
5
+ def self.scan(scanner)
6
+ scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
7
+ tokens = []
8
+ until scanner.eos?
9
+ if scanner.skip(/`(?<content>[^']+)'/)
10
+ tokens << { code: scanner[:content] }
11
+ else
12
+ char = scanner.getch
13
+ case tokens
14
+ in [*, String => last]
15
+ last << char
16
+ else
17
+ tokens << char
18
+ end
19
+ end
20
+ end
21
+ new(tokens)
22
+ end
23
+
24
+ def initialize(tokens)
25
+ @tokens = tokens
26
+ end
27
+
28
+ extend Forwardable # :nodoc:
29
+ def_delegators :@tokens, :each, :deconstruct
30
+
31
+ include Enumerable
32
+ end
33
+ end
@@ -1,3 +1,4 @@
1
1
  module Elisp2any
2
- VERSION = '0.0.4'
2
+ # Version of this library.
3
+ VERSION = '0.0.6'
3
4
  end
data/lib/elisp2any.rb CHANGED
@@ -1,8 +1,26 @@
1
1
  require_relative 'elisp2any/version'
2
- require_relative 'elisp2any/file'
2
+ require_relative 'elisp2any/heading'
3
3
 
4
4
  module Elisp2any
5
5
  autoload :HeaderLine, "elisp2any/header_line.rb"
6
6
  autoload :Blanklines, "elisp2any/blanklines.rb"
7
7
  Error = Class.new(StandardError)
8
+
9
+ def self.scan_filename(scanner) # :nodoc:
10
+ scanner.scan(/[a-z]+[.]el\b/)
11
+ end
12
+
13
+ def self.scan_variable(scanner) # :nodoc:
14
+ scanner.scan(/[a-z-]+\b/)
15
+ end
16
+
17
+ def self.scan_top_heading(scanner) # :nodoc:
18
+ pos = scanner.pos
19
+ heading = Heading.scan(scanner) or return
20
+ unless heading.level.zero?
21
+ scanner.pos = pos
22
+ return
23
+ end
24
+ heading.content
25
+ end
8
26
  end