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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +19 -0
  3. data/.gitignore +1 -0
  4. data/.overcommit.yml +54 -0
  5. data/.overcommit_gems.rb +15 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +8 -0
  8. data/.travis.yml +18 -1
  9. data/Dockerfile +8 -0
  10. data/Gemfile +0 -2
  11. data/README.md +64 -24
  12. data/Rakefile +5 -3
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/docker-compose.yml +7 -0
  16. data/front_matter_parser.gemspec +9 -5
  17. data/lib/front_matter_parser.rb +10 -114
  18. data/lib/front_matter_parser/loader.rb +11 -0
  19. data/lib/front_matter_parser/loader/yaml.rb +18 -0
  20. data/lib/front_matter_parser/parsed.rb +25 -14
  21. data/lib/front_matter_parser/parser.rb +80 -0
  22. data/lib/front_matter_parser/syntax_parser.rb +28 -0
  23. data/lib/front_matter_parser/syntax_parser/factorizable.rb +30 -0
  24. data/lib/front_matter_parser/syntax_parser/indentation_comment.rb +48 -0
  25. data/lib/front_matter_parser/syntax_parser/multi_line_comment.rb +49 -0
  26. data/lib/front_matter_parser/syntax_parser/single_line_comment.rb +63 -0
  27. data/lib/front_matter_parser/version.rb +3 -1
  28. data/spec/fixtures/example +6 -0
  29. data/spec/front_matter_parser/loader/yaml_spec.rb +15 -0
  30. data/spec/front_matter_parser/parsed_spec.rb +11 -21
  31. data/spec/front_matter_parser/parser_spec.rb +111 -0
  32. data/spec/front_matter_parser/syntax_parser/indentation_comment_spec.rb +146 -0
  33. data/spec/front_matter_parser/syntax_parser/multi_line_comment_spec.rb +249 -0
  34. data/spec/front_matter_parser/syntax_parser/single_line_comment_spec.rb +156 -0
  35. data/spec/front_matter_parser_spec.rb +3 -296
  36. data/spec/spec_helper.rb +7 -1
  37. data/spec/support/matcher.rb +8 -0
  38. metadata +86 -46
  39. data/spec/fixtures/example.coffee +0 -4
  40. data/spec/fixtures/example.erb +0 -6
  41. data/spec/fixtures/example.foo +0 -0
  42. data/spec/fixtures/example.haml +0 -5
  43. data/spec/fixtures/example.liquid +0 -6
  44. data/spec/fixtures/example.md +0 -4
  45. data/spec/fixtures/example.sass +0 -4
  46. data/spec/fixtures/example.scss +0 -4
  47. data/spec/fixtures/example.slim +0 -5
  48. data/spec/support/strings.rb +0 -41
  49. data/spec/support/syntaxs.rb +0 -14
  50. data/spec/support/utils.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 411f187a41903eee5a896a2f44262d5f38aeb085
4
- data.tar.gz: 0b2e9a84f6db0fb0f525fef1c0e64d9a27a0d668
3
+ metadata.gz: 13c37dbe3e0903b91a2e77bfbbd1c9f9688dcbc9
4
+ data.tar.gz: 9eabdd6757046433de4737ffd79d1b228e75093e
5
5
  SHA512:
6
- metadata.gz: 927cf23e937dbe7d51e77ede738b7ace2fbe110353a96b7903e66eaac52d6cefef7043524f502cdfd14b0676c84a02aa9f635966d3a161ce0cda655dd47eb60d
7
- data.tar.gz: ab89467326d6da288666290f14043a81a31afd2ecdf9b0e50b6028e0f78ecfeb46194adb69ec366e386c836f7aecfd19a19dd54af95fea12b212f1b390780958
6
+ metadata.gz: b0b6dfc6756089ac5740a5f55429c83189219dbabc9e07ab05a25dd666765a57d9fba55c6d34e65da5148ce5c7761aaec5e6666d5892a119b7952f5892e19f71
7
+ data.tar.gz: 8d8461da5eb3bb983ec19e1ec7e11b59d4028b6484e6fcb574bf0e30a7d4c2c52bf56898371cf93bb2d4ada80bd78aa572890daa1b87a85d721e4939677bdca3
@@ -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
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .overcommit_gems.rb.lock
@@ -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
@@ -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
@@ -1 +1,2 @@
1
+ --format documentation
1
2
  --color
@@ -0,0 +1,8 @@
1
+ require: rubocop-rspec
2
+ AllCops:
3
+ TargetRubyVersion: 2.4
4
+ RSpec/NestedGroups:
5
+ Max: 3
6
+ Metrics/BlockLength:
7
+ Exclude:
8
+ - "spec/**/*.rb"
@@ -1,3 +1,20 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
- - 1.9.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=
@@ -0,0 +1,8 @@
1
+ FROM ruby:2.4.0
2
+ ENV APP_HOME /app/
3
+ ENV LIB_DIR lib/front_matter_parser/
4
+ RUN mkdir -p $APP_HOME/$LIB_DIR
5
+ WORKDIR $APP_HOME
6
+ COPY Gemfile *gemspec $APP_HOME
7
+ COPY $LIB_DIR/version.rb $APP_HOME/$LIB_DIR
8
+ RUN bundle install
data/Gemfile CHANGED
@@ -1,6 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- ruby File.read('.ruby-version').strip
4
-
5
3
  # Specify your gem's dependencies in front_matter_parser.gemspec
6
4
  gemspec
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # FrontMatterParser
2
2
 
3
- FrontMatterParser is a library to parse files or strings with YAML front matters. It can automatically detect the syntax of a file from its extension and it supposes that the front matter is marked as that syntax comments.
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
- Given a file `example.md`:
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 directly `[]` method to get a front matter value:
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 comments delimiters.
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
- Given a file `example.haml`:
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
- For unknown syntaxes or alternative ones, you can provide your own single line comment delimiter with the `:comment` option, or multiline comment delimiters with `:start_comment` and `:end_comment`. If `:start_comment` is provided but it isn't `:end_comment`, then it is supposed that the multiline comment is ended by indentation.
92
+ ### Parsing a string
93
+
94
+ You can as well parse a string providing manually the syntax:
88
95
 
89
96
  ```ruby
90
- FrontMatterParser.parse_file('example.haml', start_comment: '<!--', end_comment: '-->') # start and end multiline comment delimiters
91
- FrontMatterParser.parse_file('example.slim', start_comment: '/!') # multiline comment closed by indentation
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
- ### Parsing a string
101
+ ### Custom parsers
96
102
 
97
- You can as well parse a string, providing manually the `syntax`:
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
- string = File.read('example.slim')
101
- FrontMatterParser.parse(string, syntax: :slim)
106
+ CoffeeParser = FrontMatterParser::SyntaxParser::SingleLineComment['#']
107
+ HtmlParser = FrontMatterParser::SyntaxParser::MultiLineComment['<!--', '-->']
108
+ SlimParser = FrontMatterParser::SyntaxParser::IndentationComment['/']
102
109
  ```
103
110
 
104
- or the comment delimiters:
111
+ You would use them like this:
105
112
 
106
113
  ```ruby
107
- string = File.read('example.slim')
108
- FrontMatterParser.parse(string, start_comment: '/!')
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
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ version: '2'
2
+ services:
3
+ app:
4
+ build: .
5
+ command: tail -f Gemfile
6
+ volumes:
7
+ - .:/app
@@ -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{Library to parse files or strings with YAML front matters with syntax autodetection.}
12
- spec.summary = %q{FrontMatterParser is a library to parse files or strings with YAML front matters. When working with files, it can automatically detect the syntax of a file from its extension and it supposes that the front matter is marked as that syntax comments.}
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.5", "<1.6"
22
- spec.add_development_dependency "rake", "~>10.1"
23
- spec.add_development_dependency "rspec", "~> 2.14"
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
@@ -1,117 +1,13 @@
1
- require 'yaml'
2
- require "front_matter_parser/version"
3
- require "front_matter_parser/parsed"
1
+ # frozen_string_literal: true
4
2
 
5
- # FrontMatterParser module is the entry point to parse strings or files with YAML front matters. When working with files, it can automatically detect the syntax of a file from its extension and it supposes that the front matter is marked as that syntax comments.
6
- module FrontMatterParser
7
- # {Hash {Symbol => Array}} Comments delimiters for FrontMatterParser known syntaxes. Keys are file extensions for {FrontMatterParser.parse_file} or :syntax option values for {FrontMatterParser.parse}, and values are three elements array:
8
- #
9
- # * First element is single line comment delimiter.
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
- if opts[:comment].nil? and opts[:start_comment].nil? and not opts[:syntax].nil?
49
- raise(ArgumentError, "#{opts[:syntax]} syntax not known. Please call parse providing manually comment delimiters for that syntax.") unless COMMENT_DELIMITERS.has_key?(opts[:syntax])
50
- opts[:comment], opts[:start_comment], opts[:end_comment] = COMMENT_DELIMITERS[opts[:syntax]]
51
- end
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