front_matter_parser 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +19 -0
- data/.gitignore +1 -0
- data/.overcommit.yml +54 -0
- data/.overcommit_gems.rb +15 -0
- data/.rspec +1 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +18 -1
- data/Dockerfile +8 -0
- data/Gemfile +0 -2
- data/README.md +64 -24
- data/Rakefile +5 -3
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +7 -0
- data/front_matter_parser.gemspec +9 -5
- data/lib/front_matter_parser.rb +10 -114
- data/lib/front_matter_parser/loader.rb +11 -0
- data/lib/front_matter_parser/loader/yaml.rb +18 -0
- data/lib/front_matter_parser/parsed.rb +25 -14
- data/lib/front_matter_parser/parser.rb +80 -0
- data/lib/front_matter_parser/syntax_parser.rb +28 -0
- data/lib/front_matter_parser/syntax_parser/factorizable.rb +30 -0
- data/lib/front_matter_parser/syntax_parser/indentation_comment.rb +48 -0
- data/lib/front_matter_parser/syntax_parser/multi_line_comment.rb +49 -0
- data/lib/front_matter_parser/syntax_parser/single_line_comment.rb +63 -0
- data/lib/front_matter_parser/version.rb +3 -1
- data/spec/fixtures/example +6 -0
- data/spec/front_matter_parser/loader/yaml_spec.rb +15 -0
- data/spec/front_matter_parser/parsed_spec.rb +11 -21
- data/spec/front_matter_parser/parser_spec.rb +111 -0
- data/spec/front_matter_parser/syntax_parser/indentation_comment_spec.rb +146 -0
- data/spec/front_matter_parser/syntax_parser/multi_line_comment_spec.rb +249 -0
- data/spec/front_matter_parser/syntax_parser/single_line_comment_spec.rb +156 -0
- data/spec/front_matter_parser_spec.rb +3 -296
- data/spec/spec_helper.rb +7 -1
- data/spec/support/matcher.rb +8 -0
- metadata +86 -46
- data/spec/fixtures/example.coffee +0 -4
- data/spec/fixtures/example.erb +0 -6
- data/spec/fixtures/example.foo +0 -0
- data/spec/fixtures/example.haml +0 -5
- data/spec/fixtures/example.liquid +0 -6
- data/spec/fixtures/example.md +0 -4
- data/spec/fixtures/example.sass +0 -4
- data/spec/fixtures/example.scss +0 -4
- data/spec/fixtures/example.slim +0 -5
- data/spec/support/strings.rb +0 -41
- data/spec/support/syntaxs.rb +0 -14
- data/spec/support/utils.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13c37dbe3e0903b91a2e77bfbbd1c9f9688dcbc9
|
4
|
+
data.tar.gz: 9eabdd6757046433de4737ffd79d1b228e75093e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0b6dfc6756089ac5740a5f55429c83189219dbabc9e07ab05a25dd666765a57d9fba55c6d34e65da5148ce5c7761aaec5e6666d5892a119b7952f5892e19f71
|
7
|
+
data.tar.gz: 8d8461da5eb3bb983ec19e1ec7e11b59d4028b6484e6fcb574bf0e30a7d4c2c52bf56898371cf93bb2d4ada80bd78aa572890daa1b87a85d721e4939677bdca3
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
engines:
|
2
|
+
duplication:
|
3
|
+
enabled: true
|
4
|
+
config:
|
5
|
+
languages:
|
6
|
+
- ruby
|
7
|
+
fixme:
|
8
|
+
enabled: true
|
9
|
+
rubocop:
|
10
|
+
enabled: true
|
11
|
+
reek:
|
12
|
+
enabled: true
|
13
|
+
ratings:
|
14
|
+
paths:
|
15
|
+
- "**.rb"
|
16
|
+
exclude_paths:
|
17
|
+
- spec/
|
18
|
+
- Gemfile
|
19
|
+
- front_matter_parser.gemspec
|
data/.gitignore
CHANGED
data/.overcommit.yml
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Select version of overcommit and the other tools from Gemfile
|
3
|
+
#
|
4
|
+
gemfile: .overcommit_gems.rb
|
5
|
+
|
6
|
+
#
|
7
|
+
# Hooks that are run against every commit message after a user has written it.
|
8
|
+
#
|
9
|
+
CommitMsg:
|
10
|
+
ALL:
|
11
|
+
required: true
|
12
|
+
exclude: &default_excludes
|
13
|
+
- Gemfile
|
14
|
+
- CHANGELOG.md
|
15
|
+
- front_matter_parser.gemspec
|
16
|
+
- README.md
|
17
|
+
|
18
|
+
HardTabs:
|
19
|
+
enabled: true
|
20
|
+
|
21
|
+
SingleLineSubject:
|
22
|
+
enabled: true
|
23
|
+
|
24
|
+
#
|
25
|
+
# Hooks that are run after `git commit` is executed, before the commit message
|
26
|
+
# editor is displayed.
|
27
|
+
#
|
28
|
+
PreCommit:
|
29
|
+
ALL:
|
30
|
+
required: true
|
31
|
+
exclude: *default_excludes
|
32
|
+
|
33
|
+
BundleAudit:
|
34
|
+
enabled: true
|
35
|
+
|
36
|
+
BundleCheck:
|
37
|
+
enabled: true
|
38
|
+
|
39
|
+
LocalPathsInGemfile:
|
40
|
+
enabled: true
|
41
|
+
|
42
|
+
ExecutePermissions:
|
43
|
+
enabled: true
|
44
|
+
exclude:
|
45
|
+
- bin/*
|
46
|
+
|
47
|
+
Reek:
|
48
|
+
enabled: true
|
49
|
+
|
50
|
+
RuboCop:
|
51
|
+
enabled: true
|
52
|
+
|
53
|
+
TrailingWhitespace:
|
54
|
+
enabled: true
|
data/.overcommit_gems.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gem 'overcommit', '~> 0.36'
|
6
|
+
|
7
|
+
# Patch-level verification for Bundled apps
|
8
|
+
gem 'bundler-audit', '~> 0.5'
|
9
|
+
|
10
|
+
# Ruby code smell reporter
|
11
|
+
gem 'reek', '~> 4.5'
|
12
|
+
|
13
|
+
# Ruby code style checking
|
14
|
+
gem 'rubocop', '~> 0.43'
|
15
|
+
gem 'rubocop-rspec', '~> 1.7'
|
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
sudo: false
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
|
-
-
|
4
|
+
- 2.3.3
|
5
|
+
- 2.4.0
|
6
|
+
before_install:
|
7
|
+
- gem update --system --no-doc
|
8
|
+
- bundle install --gemfile=.overcommit_gems.rb
|
9
|
+
before_script:
|
10
|
+
- git config --global user.email 'travis@travis.ci'
|
11
|
+
- git config --global user.name 'Travis CI'
|
12
|
+
script:
|
13
|
+
- bundle exec rspec
|
14
|
+
- bundle exec codeclimate-test-reporter
|
15
|
+
- overcommit --sign
|
16
|
+
- overcommit --run
|
17
|
+
addons:
|
18
|
+
code_climate:
|
19
|
+
repo_token:
|
20
|
+
secure: cgk8uvht7GhBupk3mYwjMVx73r/YzJ0YaiwKI66x150CIfvqS5bheZR/Wn6wb09llB1giuyEh32TLqbScQoPW/dFynO7FsvXIMHxn4Gup2Nkc36LkQhg+8EN3xxrzirNoqfxfaFWzJh7X/jbNdmLKLQvlh+5ey+nNPF+gdPVerXhqxg8AjE4EbDbeq3JnCi+jHlr/SxMB+zJe4PipLbeVSONSfSbraN/1IPJzHvItfQWSnEGIpRnAAb7URt2SAWcje/5CiH6QUA9C/ZyztfPEeCPfO2L1V3dp3pxbAyxzrhBtbVhw66mBO+Q6xB1xK8qv5LBQhlosn+TPOA66GMfHGo/tFP+aksq3CiVj6YfMaVy6AqzT0uocXFKvweznAfgiF5N+k4rq4+YBRXPEUtqmfaDka2hekKfewvMTDFGWQaoetU1Z/9WWJqaVlJQVSdeqYYLYpwur1wEeiPrz2nR0z3xn2LpdyGAeCpZW08dLBr/ASsjQhKGs3woIV+ZKSH3fJMmEh0CIulIm4qkcXN7izUUrNaPfNi4sUvaNNiomdLkaVbuv9hLlJByGciPHbBzajeqYFsPrGQWynHHDoFZ4/Tt2kTryNLqXGzqAqe0GozSRYx13z7frrGBYAXXMLPtViA2y568W2wiRh/MXM4noBRTQY8rETAfuaS+XuKfqTw=
|
data/Dockerfile
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# FrontMatterParser
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/front_matter_parser.svg)](https://badge.fury.io/rb/front_matter_parser)
|
4
|
+
[![Build Status](https://travis-ci.org/waiting-for-dev/front_matter_parser.svg?branch=master)](https://travis-ci.org/waiting-for-dev/front_matter_parser)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/waiting-for-dev/front_matter_parser/badges/gpa.svg)](https://codeclimate.com/github/waiting-for-dev/front_matter_parser)
|
6
|
+
[![Test Coverage](https://codeclimate.com/github/waiting-for-dev/front_matter_parser/badges/coverage.svg)](https://codeclimate.com/github/waiting-for-dev/front_matter_parser/coverage)
|
7
|
+
|
8
|
+
FrontMatterParser is a library to parse a front matter from strings or files. It allows writing syntactically correct source files, marking front matters as comments in the source file language.
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
|
@@ -24,7 +29,7 @@ Or install it yourself as:
|
|
24
29
|
|
25
30
|
Front matters must be between two lines with three dashes `---`.
|
26
31
|
|
27
|
-
|
32
|
+
For example, given a file `example.md`:
|
28
33
|
|
29
34
|
```md
|
30
35
|
---
|
@@ -37,12 +42,12 @@ Some actual content
|
|
37
42
|
You can parse it:
|
38
43
|
|
39
44
|
```ruby
|
40
|
-
parsed = FrontMatterParser.parse_file('example.md')
|
45
|
+
parsed = FrontMatterParser::Parser.parse_file('example.md')
|
41
46
|
parsed.front_matter #=> {'title' => 'Hello World', 'category' => 'Greetings'}
|
42
47
|
parsed.content #=> 'Some actual content'
|
43
48
|
```
|
44
49
|
|
45
|
-
You can apply
|
50
|
+
You can directly apply `[]` method to get a front matter value:
|
46
51
|
|
47
52
|
```ruby
|
48
53
|
parsed['category'] #=> 'Greetings'
|
@@ -50,9 +55,9 @@ parsed['category'] #=> 'Greetings'
|
|
50
55
|
|
51
56
|
### Syntax autodetection
|
52
57
|
|
53
|
-
`FrontMatterParser` detects the syntax of a file by its extension and it supposes that the front matter is within that syntax
|
58
|
+
`FrontMatterParser` detects the syntax of a file by its extension and it supposes that the front matter is within that syntax comment delimiters.
|
54
59
|
|
55
|
-
|
60
|
+
For example, given a file `example.haml`:
|
56
61
|
|
57
62
|
```haml
|
58
63
|
-#
|
@@ -65,7 +70,7 @@ Content
|
|
65
70
|
The `-#` and the indentation enclose the front matter as a comment. `FrontMatterParser` is aware of that, so you can simply do:
|
66
71
|
|
67
72
|
```ruby
|
68
|
-
title = FrontMatterParser.parse_file('example.haml')['title'] #=> 'Hello'
|
73
|
+
title = FrontMatterParser::Parser.parse_file('example.haml')['title'] #=> 'Hello'
|
69
74
|
```
|
70
75
|
|
71
76
|
Following there is a relation of known syntaxes and their known comment delimiters:
|
@@ -84,28 +89,69 @@ Following there is a relation of known syntaxes and their known comment delimite
|
|
84
89
|
| scss | // | | |
|
85
90
|
</pre>
|
86
91
|
|
87
|
-
|
92
|
+
### Parsing a string
|
93
|
+
|
94
|
+
You can as well parse a string providing manually the syntax:
|
88
95
|
|
89
96
|
```ruby
|
90
|
-
|
91
|
-
FrontMatterParser.
|
92
|
-
FrontMatterParser.parse_file('example.foo', comment: '#') # single line comments
|
97
|
+
string = File.read('example.slim')
|
98
|
+
FrontMatterParser::Parser.new(:slim).parse(string)
|
93
99
|
```
|
94
100
|
|
95
|
-
###
|
101
|
+
### Custom parsers
|
96
102
|
|
97
|
-
You can
|
103
|
+
You can implement your own parsers for other syntaxes. Most of the times, they will need to parse a syntax with single line comments, multi line comments or closed by indentation comments. For these cases, this library provides helper factory methods. For example, if they weren't already implemented, you could do something like:
|
98
104
|
|
99
105
|
```ruby
|
100
|
-
|
101
|
-
FrontMatterParser
|
106
|
+
CoffeeParser = FrontMatterParser::SyntaxParser::SingleLineComment['#']
|
107
|
+
HtmlParser = FrontMatterParser::SyntaxParser::MultiLineComment['<!--', '-->']
|
108
|
+
SlimParser = FrontMatterParser::SyntaxParser::IndentationComment['/']
|
102
109
|
```
|
103
110
|
|
104
|
-
|
111
|
+
You would use them like this:
|
105
112
|
|
106
113
|
```ruby
|
107
|
-
|
108
|
-
|
114
|
+
slim_parser = SlimParser.new
|
115
|
+
|
116
|
+
# For a file
|
117
|
+
FrontMatterParser::Parser.parse_file('example.slim', syntax_parser: slim_parser)
|
118
|
+
|
119
|
+
# For a string
|
120
|
+
FrontMatterParser::Parser.new(slim_parser).parse(string)
|
121
|
+
```
|
122
|
+
|
123
|
+
For more complex scenarios, a parser can be anything responding to a method `call(string)` which returns a hash interface with `:front_matter` and `:content` keys, or `nil` if no front matter is found.
|
124
|
+
|
125
|
+
### Custom loaders
|
126
|
+
|
127
|
+
Once a front matter is matched from a string, it is loaded as if it were a YAML text. However, you can also implement your own loaders. They just need to implement a `call(string)` method. You would use it like the following:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
json_loader = ->(string) { JSON.load(string) }
|
131
|
+
|
132
|
+
# For a file
|
133
|
+
FrontMatterParser::Parser.parse_file('example.md', loader: json_loader)
|
134
|
+
|
135
|
+
# For a string
|
136
|
+
FrontMatterParser::Parser.new(:md, loader: json_loader).parse(string)
|
137
|
+
```
|
138
|
+
|
139
|
+
## Development
|
140
|
+
|
141
|
+
There are docker and docker-compose files configured to create a development environment for this gem. So, if you use Docker you only need to run:
|
142
|
+
|
143
|
+
`docker-compose up -d`
|
144
|
+
|
145
|
+
An then, for example:
|
146
|
+
|
147
|
+
`docker-compose exec app rspec`
|
148
|
+
|
149
|
+
This gem uses [overcommit](https://github.com/brigade/overcommit) to execute some code review engines. If you submit a pull request, it will be executed in the CI process. In order to set it up, you need to do:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
bundle install --gemfile=.overcommit_gems.rb
|
153
|
+
overcommit --sign
|
154
|
+
overcommit --run # To test if it works
|
109
155
|
```
|
110
156
|
|
111
157
|
## Contributing
|
@@ -120,12 +166,6 @@ FrontMatterParser.parse(string, start_comment: '/!')
|
|
120
166
|
|
121
167
|
`front_matter_parser` follows the principles of [semantic versioning](http://semver.org/).
|
122
168
|
|
123
|
-
## To Do
|
124
|
-
|
125
|
-
* Add more known syntaxes.
|
126
|
-
* Allow configuration of global front matter delimiters. It would be easy, but I'm not sure if too useful.
|
127
|
-
* Allow different formats (as JSON). Again, I'm not sure if it would be very useful.
|
128
|
-
|
129
169
|
## Other ruby front matter parsers
|
130
170
|
|
131
171
|
* [front-matter](https://github.com/zhaocai/front-matter.rb) Can parse YAML front matters with single line comments delimiters. YAML must be correctly indented.
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'front_matter_parser'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start
|
data/bin/setup
ADDED
data/docker-compose.yml
ADDED
data/front_matter_parser.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = FrontMatterParser::VERSION
|
9
9
|
spec.authors = ["marc"]
|
10
10
|
spec.email = ["marc@lamarciana.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{Parse a front matter from syntactically correct strings or files}
|
12
|
+
spec.summary = %q{Library to parse a front matter from strings or files. It allows writing syntactically correct source files, marking front matters as comments in the source file language.}
|
13
13
|
spec.homepage = "https://github.com/waiting-for-dev/front_matter_parser"
|
14
14
|
spec.license = "LGPL3"
|
15
15
|
|
@@ -18,7 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.
|
22
|
-
spec.add_development_dependency "rake", "~>
|
23
|
-
spec.add_development_dependency "rspec", "~>
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
22
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
24
|
+
spec.add_development_dependency "pry-byebug", "~> 3.4"
|
25
|
+
# Test reporting
|
26
|
+
spec.add_development_dependency 'simplecov', '~> 0.14'
|
27
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
24
28
|
end
|
data/lib/front_matter_parser.rb
CHANGED
@@ -1,117 +1,13 @@
|
|
1
|
-
|
2
|
-
require "front_matter_parser/version"
|
3
|
-
require "front_matter_parser/parsed"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# * Second element is the start multiline comment delimiter.
|
11
|
-
# * Third element is the end multiline comment delimiter. If it is `nil` and start multiline comment delimiter isn't, it means that the comment is closed by indentation.
|
12
|
-
COMMENT_DELIMITERS = {
|
13
|
-
slim: [nil, '/', nil],
|
14
|
-
html: [nil, '<!--', '-->'],
|
15
|
-
erb: [nil, '<%#', '%>'],
|
16
|
-
coffee: ['#', nil, nil],
|
17
|
-
haml: [nil, '-#', nil],
|
18
|
-
liquid: [nil, '{% comment %}', '{% endcomment %}'],
|
19
|
-
sass: ['//', nil, nil],
|
20
|
-
scss: ['//', nil, nil],
|
21
|
-
md: [nil, nil, nil],
|
22
|
-
}
|
23
|
-
|
24
|
-
# Parses a string into a {Parsed} instance. The syntax of the string can be set with :syntax option. Otherwise, comment marks can be manually indicated with :comment, :start_comment and :end_comment options.
|
25
|
-
#
|
26
|
-
# @param string [String] The string to parse
|
27
|
-
# @param opts [Hash] Options
|
28
|
-
# @option opts [Symbol] :syntax The syntax used in the string. See {FrontMatterParser::COMMENT_DELIMITERS} for allowed values and the comment delimiters that are supposed.
|
29
|
-
# @option opts [String, nil] :comment Single line comment delimiter
|
30
|
-
# @option opts [String, nil] :start_comment Start multiline comment delimiter
|
31
|
-
# @option opts [String, nil] :end_comment End multiline comment delimiter. If it is `nil` and :start_comment isn't, the multiline comment is supposed to be closed by indentation
|
32
|
-
# @return [Parsed]
|
33
|
-
# @raise [ArgumentError] If :syntax is not within {COMMENT_DELIMITERS} keys
|
34
|
-
# @raise [ArgumentError] If :end_comment option is given but not :start_comment
|
35
|
-
# @raise [ArgumentError] If :comment and :start_comment options are given
|
36
|
-
# @see COMMENT_DELIMITERS
|
37
|
-
def self.parse(string, opts = {})
|
38
|
-
opts = {
|
39
|
-
comment: nil,
|
40
|
-
start_comment: nil,
|
41
|
-
end_comment: nil,
|
42
|
-
syntax: nil,
|
43
|
-
}.merge(opts)
|
44
|
-
|
45
|
-
raise(ArgumentError, "If you provide :end_comment, you must also provide :start_comment") if (opts[:end_comment] != nil and opts[:start_comment] == nil)
|
46
|
-
raise(ArgumentError, "You can not provide :comment and :start_comment options at the same time") if (opts[:start_comment] != nil and opts[:comment] != nil)
|
3
|
+
require 'front_matter_parser/version'
|
4
|
+
require 'front_matter_parser/syntax_parser'
|
5
|
+
require 'front_matter_parser/loader'
|
6
|
+
require 'front_matter_parser/parser'
|
7
|
+
require 'front_matter_parser/parsed'
|
47
8
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
parsed = Parsed.new
|
54
|
-
if matches = (string.match(/
|
55
|
-
# Start of string
|
56
|
-
\A
|
57
|
-
# Zero or more space characters
|
58
|
-
([[:space:]]*)
|
59
|
-
# Start multiline comment
|
60
|
-
#{'(?-x:(?<multiline_comment_indentation>^[[:blank:]]*)'+opts[:start_comment]+'[[:blank:]]*[\n\r][[:space:]]*)' unless opts[:start_comment].nil?}
|
61
|
-
# Begin front matter
|
62
|
-
(?-x:^[[:blank:]]*#{opts[:comment]}[[:blank:]]*---[[:blank:]]*$[\n\r])
|
63
|
-
# The front matter
|
64
|
-
(?<front_matter>.*)
|
65
|
-
# End front matter
|
66
|
-
(?-x:^[[:blank:]]*#{opts[:comment]}[[:blank:]]*---[[:blank:]]*$[\n\r])
|
67
|
-
# End multiline comment
|
68
|
-
#{'(?-x:\k<multiline_comment_indentation>)' if opts[:end_comment].nil? and not opts[:start_comment].nil?}
|
69
|
-
#{'(?-x:[[:space:]]*^[[:blank:]]*'+opts[:end_comment]+'[[:blank:]]*[\n\r])' if not opts[:end_comment].nil?}
|
70
|
-
# The content
|
71
|
-
(?<content>.*)
|
72
|
-
# End of string
|
73
|
-
\z
|
74
|
-
/mx))
|
75
|
-
front_matter = matches[:front_matter].gsub(/^[[:blank:]]*#{opts[:comment]}/, '')
|
76
|
-
parsed.front_matter = YAML.load(front_matter)
|
77
|
-
parsed.content = matches[:content]
|
78
|
-
else
|
79
|
-
parsed.front_matter = {}
|
80
|
-
parsed.content = string
|
81
|
-
end
|
82
|
-
parsed
|
83
|
-
end
|
84
|
-
|
85
|
-
# Parses a file into a {Parsed} instance. Syntax is automatically guessed from the file extension, unless :comment, :start_comment or :end_comment options are given. See {COMMENT_DELIMITERS} for a list of known extensions and the comment delimiters values that are supposed.
|
86
|
-
#
|
87
|
-
# @param pathname [String] The path to the file
|
88
|
-
# @param opts [Hash] Options
|
89
|
-
# @option opts [String, nil] :comment Single line comment delimiter
|
90
|
-
# @option opts [String, nil] :start_comment Start multiline comment delimiter
|
91
|
-
# @option opts [String, nil] :end_comment End multiline comment delimiter. If it is `nil`, the multiline comment is supposed to be closed by indentation.
|
92
|
-
# @return [Parsed]
|
93
|
-
# @raise [ArgumentError] If :start_comment option is provided but not :end_comment
|
94
|
-
# @raise [ArgumentError] If :comment and :start_comment options are both provided
|
95
|
-
# @raise [ArgumentError] If :end_comment is provided but :start_comment isn't
|
96
|
-
# @raise [RuntimeError] If the syntax of the file (the extension) is not within the keys of {COMMENT_DELIMITERS} or the file has no extension, and none of :comment, :start_comment or :end_comment are provided
|
97
|
-
# @see COMMENT_DELIMITERS
|
98
|
-
def self.parse_file(pathname, opts={})
|
99
|
-
opts = {
|
100
|
-
comment: nil,
|
101
|
-
start_comment: nil,
|
102
|
-
end_comment: nil,
|
103
|
-
}.merge(opts)
|
104
|
-
if opts[:comment].nil? and opts[:start_comment].nil?
|
105
|
-
ext = File.extname(pathname)[1 .. -1]
|
106
|
-
ext = ext.to_sym unless ext.nil?
|
107
|
-
raise(RuntimeError, "Comment delimiters for extension #{ext.to_s} not known. Please, call #parse_file providing manually comment delimiters for that extension.") unless COMMENT_DELIMITERS.has_key?(ext)
|
108
|
-
File.open(pathname) do |file|
|
109
|
-
parse(file.read, syntax: ext)
|
110
|
-
end
|
111
|
-
else
|
112
|
-
File.open(pathname) do |file|
|
113
|
-
parse(file.read, comment: opts[:comment], start_comment: opts[:start_comment], end_comment: opts[:end_comment])
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
9
|
+
# FrontMatterParser is a library to parse a front matter from strings or
|
10
|
+
# files. It allows writing syntactically correct source files, marking front
|
11
|
+
# matters as comments in the source file language.
|
12
|
+
module FrontMatterParser
|
117
13
|
end
|