front_matter_parser 0.0.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.codeclimate.yml +19 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +19 -1
- data/CHANGELOG.md +30 -0
- data/Dockerfile +5 -0
- data/Gemfile +0 -2
- data/README.md +76 -38
- data/Rakefile +5 -3
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +12 -0
- data/front_matter_parser.gemspec +12 -6
- 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 +26 -0
- data/lib/front_matter_parser/parsed.rb +25 -14
- data/lib/front_matter_parser/parser.rb +82 -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 +49 -0
- data/lib/front_matter_parser/syntax_parser/multi_line_comment.rb +50 -0
- data/lib/front_matter_parser/syntax_parser/single_line_comment.rb +64 -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 +24 -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 +166 -0
- data/spec/front_matter_parser/syntax_parser/multi_line_comment_spec.rb +267 -0
- data/spec/front_matter_parser/syntax_parser/single_line_comment_spec.rb +175 -0
- data/spec/front_matter_parser_spec.rb +3 -296
- data/spec/spec_helper.rb +9 -3
- data/spec/support/matcher.rb +8 -0
- metadata +110 -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
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a904dbf5bade2127e0bb2b9abb7106f179ce22876ca6e57aa9dc7c89730d2898
|
4
|
+
data.tar.gz: b43330122a6496888be51b937fc06749dd0b256394227425736b88a0e9e9f781
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf46ac330a47187dc37041b4c25ec6dd8500761ec18feaa2102659e19cda516f03be66b3ac32a9a530406b9d4fe598a86666916418ddf54f5380d9c164787095
|
7
|
+
data.tar.gz: 1d359953cd78bac9bf7186eb5b16e22f95a4d01ddaaf3d9e643580c7d407332f6730573733aa55423fd06c147e7816873b8deb62b1f1fa59ac7429e0f1490489
|
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/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
AllCops:
|
3
|
+
TargetRubyVersion: 3.0
|
4
|
+
Exclude:
|
5
|
+
- Gemfile
|
6
|
+
- front_matter_parser.gemspec
|
7
|
+
- vendor/**/*
|
8
|
+
RSpec/NestedGroups:
|
9
|
+
Max: 3
|
10
|
+
RSpec/MessageExpectation:
|
11
|
+
EnforcedStyle: 'expect'
|
12
|
+
Metrics/BlockLength:
|
13
|
+
Exclude:
|
14
|
+
- "spec/**/*.rb"
|
15
|
+
Style/SafeNavigation:
|
16
|
+
Enabled: false
|
17
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
18
|
+
Enabled: true
|
19
|
+
Layout/SpaceAroundMethodCallOperator:
|
20
|
+
Enabled: true
|
21
|
+
Lint/DeprecatedOpenSSLConstant:
|
22
|
+
Enabled: true
|
23
|
+
Lint/MixedRegexpCaptureTypes:
|
24
|
+
Enabled: true
|
25
|
+
Lint/RaiseException:
|
26
|
+
Enabled: true
|
27
|
+
Lint/StructNewOverride:
|
28
|
+
Enabled: true
|
29
|
+
Style/AccessorGrouping:
|
30
|
+
Enabled: true
|
31
|
+
Style/BisectedAttrAccessor:
|
32
|
+
Enabled: true
|
33
|
+
Style/ExponentialNotation:
|
34
|
+
Enabled: true
|
35
|
+
Style/HashEachMethods:
|
36
|
+
Enabled: true
|
37
|
+
Style/HashTransformKeys:
|
38
|
+
Enabled: true
|
39
|
+
Style/HashTransformValues:
|
40
|
+
Enabled: true
|
41
|
+
Style/RedundantAssignment:
|
42
|
+
Enabled: true
|
43
|
+
Style/RedundantFetchBlock:
|
44
|
+
Enabled: true
|
45
|
+
Style/RedundantRegexpCharacterClass:
|
46
|
+
Enabled: true
|
47
|
+
Style/RedundantRegexpEscape:
|
48
|
+
Enabled: true
|
49
|
+
Style/SlicingWithRange:
|
50
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,3 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
2
3
|
rvm:
|
3
|
-
-
|
4
|
+
- 2.6
|
5
|
+
- 2.7
|
6
|
+
- 3.0
|
7
|
+
- ruby-head
|
8
|
+
before_install:
|
9
|
+
- gem update --system --no-doc
|
10
|
+
- gem install bundler
|
11
|
+
script:
|
12
|
+
- bundle exec rspec
|
13
|
+
- bundle exec rubocop
|
14
|
+
- bundle exec codeclimate-test-reporter
|
15
|
+
jobs:
|
16
|
+
allow_failures:
|
17
|
+
- rvm: ruby-head
|
18
|
+
addons:
|
19
|
+
code_climate:
|
20
|
+
repo_token:
|
21
|
+
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/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
## [1.0.0] - 2020-08-31
|
8
|
+
- Depreciate "whitelist" in favor of "allowlist" by renaming the `whitelist_classes` param to `allowlist_classes`.
|
9
|
+
|
10
|
+
If your project uses the `whitelist_classes` param, you will need to upgrade your code as follows:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
## before
|
14
|
+
loader = FrontMatterParser::Loader::Yaml.new(whitelist_classes: [Time])
|
15
|
+
|
16
|
+
## after
|
17
|
+
loader = FrontMatterParser::Loader::Yaml.new(allowlist_classes: [Time])
|
18
|
+
```
|
19
|
+
|
20
|
+
## [0.2.1] - 2019-06-06
|
21
|
+
### Fixed
|
22
|
+
- Do not add `bin` development executables to generated gem.
|
23
|
+
|
24
|
+
## [0.2.0] - 2018-06-11
|
25
|
+
### Added
|
26
|
+
- Allow whitelisting classes in YAML loader.
|
27
|
+
|
28
|
+
## [0.1.1] - 2017-07-19
|
29
|
+
### Fixed
|
30
|
+
- Don't be greedy with front matter end delimiters.
|
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,49 +70,88 @@ 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:
|
72
77
|
|
73
|
-
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
78
|
+
| Syntax | Single line comment | Start multiline comment | End multiline comment |
|
79
|
+
| ------ | ------------------- | ----------------------- | --------------------- |
|
80
|
+
| haml | | -# | (indentation) |
|
81
|
+
| slim | | / | (indentation) |
|
82
|
+
| liquid | | {% comment %} | {% endcomment %} |
|
83
|
+
| md | | | |
|
84
|
+
| html | | <!-- | --> |
|
85
|
+
| erb | | <%# | %> |
|
86
|
+
| coffee | # | | |
|
87
|
+
| sass | // | | |
|
88
|
+
| scss | // | | |
|
89
|
+
|
90
|
+
### Parsing a string
|
91
|
+
|
92
|
+
You can as well parse a string providing manually the syntax:
|
88
93
|
|
89
94
|
```ruby
|
90
|
-
|
91
|
-
FrontMatterParser.
|
92
|
-
FrontMatterParser.parse_file('example.foo', comment: '#') # single line comments
|
95
|
+
string = File.read('example.slim')
|
96
|
+
FrontMatterParser::Parser.new(:slim).call(string)
|
93
97
|
```
|
94
98
|
|
95
|
-
###
|
99
|
+
### Custom parsers
|
96
100
|
|
97
|
-
You can
|
101
|
+
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
102
|
|
99
103
|
```ruby
|
100
|
-
|
101
|
-
FrontMatterParser
|
104
|
+
CoffeeParser = FrontMatterParser::SyntaxParser::SingleLineComment['#']
|
105
|
+
HtmlParser = FrontMatterParser::SyntaxParser::MultiLineComment['<!--', '-->']
|
106
|
+
SlimParser = FrontMatterParser::SyntaxParser::IndentationComment['/']
|
102
107
|
```
|
103
108
|
|
104
|
-
|
109
|
+
You would use them like this:
|
105
110
|
|
106
111
|
```ruby
|
107
|
-
|
108
|
-
|
112
|
+
slim_parser = SlimParser.new
|
113
|
+
|
114
|
+
# For a file
|
115
|
+
FrontMatterParser::Parser.parse_file('example.slim', syntax_parser: slim_parser)
|
116
|
+
|
117
|
+
# For a string
|
118
|
+
FrontMatterParser::Parser.new(slim_parser).call(string)
|
109
119
|
```
|
110
120
|
|
121
|
+
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.
|
122
|
+
|
123
|
+
### Custom loaders
|
124
|
+
|
125
|
+
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:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
json_loader = ->(string) { JSON.load(string) }
|
129
|
+
|
130
|
+
# For a file
|
131
|
+
FrontMatterParser::Parser.parse_file('example.md', loader: json_loader)
|
132
|
+
|
133
|
+
# For a string
|
134
|
+
FrontMatterParser::Parser.new(:md, loader: json_loader).call(string)
|
135
|
+
```
|
136
|
+
|
137
|
+
If you need to allow one or more classes for the built-in YAML loader, you can just create a custom loader based on it and provide needed classes in a `allowlist_classes:` param:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
loader = FrontMatterParser::Loader::Yaml.new(allowlist_classes: [Time])
|
141
|
+
parsed = FrontMatterParser::Parser.parse_file('example.md', loader: loader)
|
142
|
+
puts parsed['timestamp']
|
143
|
+
```
|
144
|
+
|
145
|
+
## Development
|
146
|
+
|
147
|
+
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:
|
148
|
+
|
149
|
+
`docker-compose up -d`
|
150
|
+
|
151
|
+
An then, for example:
|
152
|
+
|
153
|
+
`docker-compose exec app rspec`
|
154
|
+
|
111
155
|
## Contributing
|
112
156
|
|
113
157
|
1. Fork it
|
@@ -120,12 +164,6 @@ FrontMatterParser.parse(string, start_comment: '/!')
|
|
120
164
|
|
121
165
|
`front_matter_parser` follows the principles of [semantic versioning](http://semver.org/).
|
122
166
|
|
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
167
|
## Other ruby front matter parsers
|
130
168
|
|
131
169
|
* [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,17 +8,23 @@ 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
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
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"
|
22
|
-
spec.add_development_dependency "rake", "~>
|
23
|
-
spec.add_development_dependency "rspec", "~>
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.8"
|
24
|
+
spec.add_development_dependency "pry-byebug", "~> 3.7"
|
25
|
+
# Test reporting
|
26
|
+
spec.add_development_dependency 'rubocop', '~> 1.9'
|
27
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
|
28
|
+
spec.add_development_dependency 'simplecov', '0.17'
|
29
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
24
30
|
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
|