elisp2any 0.0.6 → 0.0.8
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.
- checksums.yaml +4 -4
- data/.envrc +2 -0
- data/CHANGELOG.md +15 -0
- data/README.md +39 -3
- data/Rakefile +12 -6
- data/exe/elisp2any +45 -4
- data/lib/elisp/comment.rb +15 -80
- data/lib/elisp/default.css +11 -0
- data/lib/elisp/doc_string_parser.rb +217 -0
- data/lib/elisp/heading.rb +47 -0
- data/lib/elisp/parser.rb +39 -50
- data/lib/elisp/version.rb +18 -0
- data/lib/elisp.rb +92 -65
- data/sample.md +30 -0
- metadata +9 -26
- data/lib/elisp2any/aside.rb +0 -23
- data/lib/elisp2any/blanklines.rb +0 -20
- data/lib/elisp2any/code.rb +0 -49
- data/lib/elisp2any/codeblock.rb +0 -56
- data/lib/elisp2any/comment.rb +0 -19
- data/lib/elisp2any/commentary.rb +0 -32
- data/lib/elisp2any/expression.rb +0 -90
- data/lib/elisp2any/footer_line.rb +0 -28
- data/lib/elisp2any/header_line.rb +0 -80
- data/lib/elisp2any/heading.rb +0 -68
- data/lib/elisp2any/html_renderer/index.html.erb +0 -23
- data/lib/elisp2any/html_renderer.erb +0 -22
- data/lib/elisp2any/html_renderer.rb +0 -149
- data/lib/elisp2any/inline_code.rb +0 -10
- data/lib/elisp2any/line.rb +0 -52
- data/lib/elisp2any/paragraph.rb +0 -37
- data/lib/elisp2any/section.rb +0 -49
- data/lib/elisp2any/text.rb +0 -33
- data/lib/elisp2any/version.rb +0 -4
- data/lib/elisp2any.rb +0 -26
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (C) 2025, 2026 gemmaro
|
|
2
|
+
#
|
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
class Elisp
|
|
17
|
+
VERSION = "0.0.8"
|
|
18
|
+
end
|
data/lib/elisp.rb
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# Copyright (C) 2025, 2026 gemmaro
|
|
2
|
+
#
|
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
require "cgi/escape"
|
|
17
|
+
|
|
18
|
+
# +pandoc_json_object+ methods for some classes means the AST for the
|
|
19
|
+
# Pandoc JSON filter.
|
|
5
20
|
class Elisp
|
|
6
21
|
Error = Class.new(StandardError)
|
|
7
22
|
|
|
@@ -10,67 +25,12 @@ class Elisp
|
|
|
10
25
|
end
|
|
11
26
|
end
|
|
12
27
|
|
|
13
|
-
class Elisp::
|
|
14
|
-
def initialize(headings)
|
|
15
|
-
@headings = headings
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def html
|
|
19
|
-
rest = @headings.dup
|
|
20
|
-
result = +""
|
|
21
|
-
while (head = rest.shift)
|
|
22
|
-
level = head.level
|
|
23
|
-
subheadings = []
|
|
24
|
-
while (heading = rest.shift)
|
|
25
|
-
if heading.level > level
|
|
26
|
-
subheadings << heading
|
|
27
|
-
else
|
|
28
|
-
rest.unshift(heading)
|
|
29
|
-
break
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
sub_sidebar =
|
|
33
|
-
subheadings.empty? ? nil
|
|
34
|
-
: (html = self.class.new(subheadings).html
|
|
35
|
-
"<details open>#{html}</details>")
|
|
36
|
-
content = CGI.escape_html(head.content)
|
|
37
|
-
result << <<~END_HTML
|
|
38
|
-
<li>
|
|
39
|
-
<a href="##{head.html_id}">#{content}</a>
|
|
40
|
-
#{sub_sidebar}
|
|
41
|
-
</li>
|
|
42
|
-
END_HTML
|
|
43
|
-
end
|
|
44
|
-
"<ul>#{result}</ul>"
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class PageDelimiter
|
|
28
|
+
class Elisp::PageDelimiter
|
|
49
29
|
def html = "<hr>"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def initialize(content, level: 2)
|
|
56
|
-
@content = content
|
|
57
|
-
@level = level
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def html
|
|
61
|
-
name = "h#{@level}"
|
|
62
|
-
content = CGI.escape_html(@content)
|
|
63
|
-
<<~END_HTML
|
|
64
|
-
<#{name} id="#{html_id}">
|
|
65
|
-
#{content}
|
|
66
|
-
<a href="##{html_id}">#</a>
|
|
67
|
-
</#{name}>
|
|
68
|
-
END_HTML
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def html_id
|
|
72
|
-
content = CGI.escape(@content)
|
|
73
|
-
"#{@level}-#{content}"
|
|
30
|
+
def pandoc_json_object
|
|
31
|
+
{
|
|
32
|
+
"t": "HorizontalRule",
|
|
33
|
+
}
|
|
74
34
|
end
|
|
75
35
|
end
|
|
76
36
|
|
|
@@ -83,6 +43,26 @@ class Elisp::Desc
|
|
|
83
43
|
content = CGI.escape_html(@content)
|
|
84
44
|
%(<p class="description">#{content}</p>)
|
|
85
45
|
end
|
|
46
|
+
|
|
47
|
+
def pandoc_json_object
|
|
48
|
+
{
|
|
49
|
+
"t": "Div",
|
|
50
|
+
"c": [
|
|
51
|
+
["", ["description"], []],
|
|
52
|
+
[
|
|
53
|
+
{
|
|
54
|
+
"t": "Para",
|
|
55
|
+
"c": [
|
|
56
|
+
{
|
|
57
|
+
"t": "Str",
|
|
58
|
+
"c": @content,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
],
|
|
64
|
+
}
|
|
65
|
+
end
|
|
86
66
|
end
|
|
87
67
|
|
|
88
68
|
class Elisp::Variables
|
|
@@ -95,10 +75,28 @@ class Elisp::Variables
|
|
|
95
75
|
<<~END_HTML
|
|
96
76
|
<article>
|
|
97
77
|
Header line variables:
|
|
98
|
-
<pre><code>#{content}</code></pre>
|
|
78
|
+
<pre class="code"><code>#{content}</code></pre>
|
|
99
79
|
</article>
|
|
100
80
|
END_HTML
|
|
101
81
|
end
|
|
82
|
+
|
|
83
|
+
def pandoc_json_object
|
|
84
|
+
{
|
|
85
|
+
"t": "Div",
|
|
86
|
+
"c": [
|
|
87
|
+
["", ["header-line-variables"], []],
|
|
88
|
+
[
|
|
89
|
+
{
|
|
90
|
+
"t": "CodeBlock",
|
|
91
|
+
"c": [
|
|
92
|
+
["", ["emacs-lisp-header-line-variables"], []],
|
|
93
|
+
@content,
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
],
|
|
98
|
+
}
|
|
99
|
+
end
|
|
102
100
|
end
|
|
103
101
|
|
|
104
102
|
class Elisp::MajorPara
|
|
@@ -110,6 +108,16 @@ class Elisp::MajorPara
|
|
|
110
108
|
paras = @paras.map(&:html).join("\n")
|
|
111
109
|
"<article>#{paras}</article>"
|
|
112
110
|
end
|
|
111
|
+
|
|
112
|
+
def pandoc_json_object
|
|
113
|
+
{
|
|
114
|
+
"t": "Div",
|
|
115
|
+
"c": [
|
|
116
|
+
["", ["major-para"], []],
|
|
117
|
+
@paras.map(&:pandoc_json_object),
|
|
118
|
+
],
|
|
119
|
+
}
|
|
120
|
+
end
|
|
113
121
|
end
|
|
114
122
|
|
|
115
123
|
class Elisp::MinorPara
|
|
@@ -121,6 +129,13 @@ class Elisp::MinorPara
|
|
|
121
129
|
content = Elisp::DocStringParser.new(@content).html
|
|
122
130
|
"<pre>#{content}</pre>"
|
|
123
131
|
end
|
|
132
|
+
|
|
133
|
+
def pandoc_json_object
|
|
134
|
+
{
|
|
135
|
+
"t": "Para",
|
|
136
|
+
"c": Elisp::DocStringParser.new(@content).pandoc_json_objects,
|
|
137
|
+
}
|
|
138
|
+
end
|
|
124
139
|
end
|
|
125
140
|
|
|
126
141
|
class Elisp::Code
|
|
@@ -136,7 +151,19 @@ class Elisp::Code
|
|
|
136
151
|
content = CGI.escape_html(@content)
|
|
137
152
|
%(<pre class="code"><code>#{content}</code></pre>)
|
|
138
153
|
end
|
|
154
|
+
|
|
155
|
+
def pandoc_json_object
|
|
156
|
+
{
|
|
157
|
+
"t": "CodeBlock",
|
|
158
|
+
"c": [
|
|
159
|
+
["", ["emacs-lisp"], []],
|
|
160
|
+
@content,
|
|
161
|
+
],
|
|
162
|
+
}
|
|
163
|
+
end
|
|
139
164
|
end
|
|
140
165
|
|
|
141
166
|
require_relative "elisp/comment"
|
|
142
167
|
require_relative "elisp/parser"
|
|
168
|
+
require_relative "elisp/heading"
|
|
169
|
+
require_relative "elisp/doc_string_parser"
|
data/sample.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
これはページ区切りです:
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
これはコードブロックです:
|
|
6
|
+
|
|
7
|
+
```emacs-lisp
|
|
8
|
+
(message "hello")
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
これは有塀divです:
|
|
12
|
+
|
|
13
|
+
::: majorpara
|
|
14
|
+
段落1つ目。
|
|
15
|
+
|
|
16
|
+
段落2つ目。
|
|
17
|
+
:::
|
|
18
|
+
|
|
19
|
+
なお、普通の段落はminor paraです。
|
|
20
|
+
|
|
21
|
+
行内コード`aaa`を確かめます。
|
|
22
|
+
|
|
23
|
+
# これは見出しです
|
|
24
|
+
|
|
25
|
+
生のHTMLリンク https://example.com です。
|
|
26
|
+
生のHTMLリンク <https://example.com> です。
|
|
27
|
+
|
|
28
|
+
これは著作情報 Copyright (C) gemmaro です。
|
|
29
|
+
|
|
30
|
+
これは電子メール<gemmaro.dev@gmail.com>です。
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elisp2any
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- gemmaro
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rake
|
|
@@ -47,6 +46,7 @@ executables:
|
|
|
47
46
|
extensions: []
|
|
48
47
|
extra_rdoc_files: []
|
|
49
48
|
files:
|
|
49
|
+
- ".envrc"
|
|
50
50
|
- CHANGELOG.md
|
|
51
51
|
- Gemfile
|
|
52
52
|
- LICENSE.txt
|
|
@@ -56,27 +56,12 @@ files:
|
|
|
56
56
|
- fixtures/init.el
|
|
57
57
|
- lib/elisp.rb
|
|
58
58
|
- lib/elisp/comment.rb
|
|
59
|
+
- lib/elisp/default.css
|
|
60
|
+
- lib/elisp/doc_string_parser.rb
|
|
61
|
+
- lib/elisp/heading.rb
|
|
59
62
|
- lib/elisp/parser.rb
|
|
60
|
-
- lib/
|
|
61
|
-
-
|
|
62
|
-
- lib/elisp2any/blanklines.rb
|
|
63
|
-
- lib/elisp2any/code.rb
|
|
64
|
-
- lib/elisp2any/codeblock.rb
|
|
65
|
-
- lib/elisp2any/comment.rb
|
|
66
|
-
- lib/elisp2any/commentary.rb
|
|
67
|
-
- lib/elisp2any/expression.rb
|
|
68
|
-
- lib/elisp2any/footer_line.rb
|
|
69
|
-
- lib/elisp2any/header_line.rb
|
|
70
|
-
- lib/elisp2any/heading.rb
|
|
71
|
-
- lib/elisp2any/html_renderer.erb
|
|
72
|
-
- lib/elisp2any/html_renderer.rb
|
|
73
|
-
- lib/elisp2any/html_renderer/index.html.erb
|
|
74
|
-
- lib/elisp2any/inline_code.rb
|
|
75
|
-
- lib/elisp2any/line.rb
|
|
76
|
-
- lib/elisp2any/paragraph.rb
|
|
77
|
-
- lib/elisp2any/section.rb
|
|
78
|
-
- lib/elisp2any/text.rb
|
|
79
|
-
- lib/elisp2any/version.rb
|
|
63
|
+
- lib/elisp/version.rb
|
|
64
|
+
- sample.md
|
|
80
65
|
homepage: https://codeberg.org/gemmaro/elisp2any
|
|
81
66
|
licenses:
|
|
82
67
|
- GPL-3.0-or-later
|
|
@@ -88,7 +73,6 @@ metadata:
|
|
|
88
73
|
homepage_uri: https://codeberg.org/gemmaro/elisp2any
|
|
89
74
|
source_code_uri: https://codeberg.org/gemmaro/elisp2any
|
|
90
75
|
wiki_uri: https://codeberg.org/gemmaro/elisp2any/wiki
|
|
91
|
-
post_install_message:
|
|
92
76
|
rdoc_options: []
|
|
93
77
|
require_paths:
|
|
94
78
|
- lib
|
|
@@ -103,8 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
103
87
|
- !ruby/object:Gem::Version
|
|
104
88
|
version: '0'
|
|
105
89
|
requirements: []
|
|
106
|
-
rubygems_version:
|
|
107
|
-
signing_key:
|
|
90
|
+
rubygems_version: 4.0.16
|
|
108
91
|
specification_version: 4
|
|
109
92
|
summary: Converter from Emacs Lisp to some document markup
|
|
110
93
|
test_files: []
|
data/lib/elisp2any/aside.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require "elisp2any/comment"
|
|
2
|
-
|
|
3
|
-
module Elisp2any
|
|
4
|
-
class Aside
|
|
5
|
-
def self.scan(scanner)
|
|
6
|
-
pos = scanner.pos
|
|
7
|
-
com = Comment.scan(scanner) or return
|
|
8
|
-
unless com.colons == 1
|
|
9
|
-
scanner.pos = pos
|
|
10
|
-
return
|
|
11
|
-
end
|
|
12
|
-
new(com.content)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def source
|
|
16
|
-
";#{@content}\n"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def initialize(content)
|
|
20
|
-
@content = content
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/elisp2any/blanklines.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require "forwardable"
|
|
2
|
-
|
|
3
|
-
module Elisp2any
|
|
4
|
-
class Blanklines
|
|
5
|
-
def self.scan(scanner)
|
|
6
|
-
scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
|
|
7
|
-
count = 0
|
|
8
|
-
count += 1 while !scanner.eos? && scanner.skip(/ *\n/)
|
|
9
|
-
count.zero? and return
|
|
10
|
-
new(count)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def initialize(count) # :nodoc:
|
|
14
|
-
@count = count
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
extend Forwardable # :nodoc:
|
|
18
|
-
def_delegator :@count, :to_i
|
|
19
|
-
end
|
|
20
|
-
end
|
data/lib/elisp2any/code.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require "forwardable"
|
|
2
|
-
require "elisp2any/paragraph"
|
|
3
|
-
require "elisp2any/blanklines"
|
|
4
|
-
require "elisp2any/section"
|
|
5
|
-
|
|
6
|
-
module Elisp2any
|
|
7
|
-
class Code
|
|
8
|
-
def self.scan(scanner)
|
|
9
|
-
pos = scanner.pos
|
|
10
|
-
heading = Elisp2any.scan_top_heading(scanner) or return
|
|
11
|
-
unless heading == "Code:"
|
|
12
|
-
scanner.pos = pos
|
|
13
|
-
return
|
|
14
|
-
end
|
|
15
|
-
Blanklines.scan(scanner) # optional
|
|
16
|
-
paragraphs = []
|
|
17
|
-
while (par = Paragraph.scan(scanner))
|
|
18
|
-
paragraphs << par
|
|
19
|
-
Blanklines.scan(scanner) # optional
|
|
20
|
-
end
|
|
21
|
-
blocks = [paragraphs]
|
|
22
|
-
pos = scanner.pos
|
|
23
|
-
while (section = Section.scan(scanner))
|
|
24
|
-
if section.heading.level == 1
|
|
25
|
-
blocks << section
|
|
26
|
-
pos = scanner.pos
|
|
27
|
-
else
|
|
28
|
-
scanner.pos = pos
|
|
29
|
-
break
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
new(blocks)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def initialize(blocks)
|
|
36
|
-
@blocks = blocks
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def sections
|
|
40
|
-
@blocks.drop(1)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
extend Forwardable # :nodoc:
|
|
44
|
-
def_delegator :@blocks, :first, :paragraphs
|
|
45
|
-
def_delegator :@blocks, :each
|
|
46
|
-
|
|
47
|
-
include Enumerable
|
|
48
|
-
end
|
|
49
|
-
end
|
data/lib/elisp2any/codeblock.rb
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require "forwardable"
|
|
2
|
-
require "elisp2any/expression"
|
|
3
|
-
require "elisp2any/blanklines"
|
|
4
|
-
require "elisp2any/aside"
|
|
5
|
-
|
|
6
|
-
module Elisp2any
|
|
7
|
-
class Codeblock # :nodoc:
|
|
8
|
-
def self.scan(scanner)
|
|
9
|
-
scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
|
|
10
|
-
expressions = []
|
|
11
|
-
while (exp = Expression.scan(scanner) ||
|
|
12
|
-
scanner.scan(/[ \n]+/) ||
|
|
13
|
-
Aside.scan(scanner))
|
|
14
|
-
expressions << exp
|
|
15
|
-
end
|
|
16
|
-
expressions.empty? and return
|
|
17
|
-
Blanklines.scan(scanner) # optional
|
|
18
|
-
new(:TODO, expressions:)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def source
|
|
22
|
-
@expressions.sum(+"") do |exp|
|
|
23
|
-
case exp
|
|
24
|
-
in String
|
|
25
|
-
exp
|
|
26
|
-
else
|
|
27
|
-
exp.source
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# TODO: delete node
|
|
33
|
-
# TODO: Remove default empty array
|
|
34
|
-
def initialize(node, expressions: []) # :nodoc:
|
|
35
|
-
@node = node
|
|
36
|
-
@expressions = expressions
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def append(source, end_byte) # :nodoc:
|
|
40
|
-
@node.append(source, end_byte)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def content
|
|
44
|
-
if @node.respond_to?(:content)
|
|
45
|
-
@node.content
|
|
46
|
-
else
|
|
47
|
-
@expressions
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
extend Forwardable # :nodoc:
|
|
52
|
-
def_delegator :@expressions, :each
|
|
53
|
-
|
|
54
|
-
include Enumerable
|
|
55
|
-
end
|
|
56
|
-
end
|
data/lib/elisp2any/comment.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module Elisp2any
|
|
2
|
-
class Comment
|
|
3
|
-
attr_reader :colons, :content, :padding
|
|
4
|
-
|
|
5
|
-
def self.scan(scanner)
|
|
6
|
-
scanner = StringScanner.new(scanner) unless scanner.respond_to?(:skip)
|
|
7
|
-
scanner.skip(/(?<colons>;+)(?<padding> *)(?<content>.*)\n?/) or return
|
|
8
|
-
new(colons: scanner[:colons].size,
|
|
9
|
-
content: scanner[:content],
|
|
10
|
-
padding: scanner[:padding])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def initialize(colons:, content:, padding:)
|
|
14
|
-
@colons = colons
|
|
15
|
-
@content = content
|
|
16
|
-
@padding = padding
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/elisp2any/commentary.rb
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
require "forwardable"
|
|
2
|
-
require "elisp2any/paragraph"
|
|
3
|
-
require "elisp2any/blanklines"
|
|
4
|
-
|
|
5
|
-
module Elisp2any
|
|
6
|
-
class Commentary
|
|
7
|
-
def self.scan(scanner)
|
|
8
|
-
pos = scanner.pos
|
|
9
|
-
heading = Elisp2any.scan_top_heading(scanner) or return
|
|
10
|
-
unless heading == "Commentary:"
|
|
11
|
-
scanner.pos = pos
|
|
12
|
-
return
|
|
13
|
-
end
|
|
14
|
-
Blanklines.scan(scanner) # optional
|
|
15
|
-
paragraphs = []
|
|
16
|
-
while (par = Paragraph.scan(scanner))
|
|
17
|
-
paragraphs << par
|
|
18
|
-
Blanklines.scan(scanner) # optional
|
|
19
|
-
end
|
|
20
|
-
new(paragraphs)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def initialize(paragraphs)
|
|
24
|
-
@paragraphs = paragraphs
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
extend Forwardable # :nodoc:
|
|
28
|
-
def_delegators :@paragraphs, :each, :size
|
|
29
|
-
|
|
30
|
-
include Enumerable
|
|
31
|
-
end
|
|
32
|
-
end
|
data/lib/elisp2any/expression.rb
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
require "strscan"
|
|
2
|
-
|
|
3
|
-
module Elisp2any
|
|
4
|
-
class Expression
|
|
5
|
-
def self.scan(scanner)
|
|
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]
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def initialize(content)
|
|
87
|
-
@content = content
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
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
|