md_to_bbcode 1.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 30246a88b518806835d54cc211033ee2204fc1e970c78e446cae7e6b97d3c7c2
4
+ data.tar.gz: 7ca2a66301454a044269065b8e49366f533ba9cd4f0600ac8003341e704bcdf8
5
+ SHA512:
6
+ metadata.gz: 2c3008f40d593f396206c92a4254aa6fedc2e81fcc23e255d78f470a142c144eac82076ee6847e1b51d1a19c6b3937383deee37fc0084b206d4c6c9ebe085239
7
+ data.tar.gz: 99ed4f207dcb62f868e85b2f81758a898b07ff733a19cc9a470c6e22ff087a07dad458a3f5c07059ba9c1d2be2686a9af82fd22dd2742fa19e5a39a01328feeb
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ require 'md_to_bbcode'
3
+ require 'md_to_bbcode/version'
4
+ require 'optparse'
5
+
6
+ markdown_file = nil
7
+ bbcode_file = nil
8
+ opts_parser = OptionParser.new do |opts|
9
+ opts.banner = 'Usage: md_to_bbcode [options]'
10
+ opts.on('-h', '--help', 'Display this help') do
11
+ puts opts
12
+ exit 0
13
+ end
14
+ opts.on('-i', '--input MARKDOWN_FILE', 'Specify the input Markdown file to convert (mandatory)') do |file|
15
+ markdown_file = file
16
+ end
17
+ opts.on('-o', '--output BBCODE_FILE', 'Specify the output BBCode file to write (outputs to stdout if not specified') do |file|
18
+ bbcode_file = file
19
+ end
20
+ opts.on('-v', '--version', 'Display version') do
21
+ puts "md_to_bbcode v#{MdToBbcode::VERSION}"
22
+ exit 0
23
+ end
24
+ end
25
+ opts_parser.parse!
26
+
27
+ if !ARGV.empty? || markdown_file.nil?
28
+ puts opts_parser
29
+ exit 1
30
+ end
31
+
32
+ unless File.exist?(markdown_file)
33
+ puts "Missing file #{markdown_file}"
34
+ exit 2
35
+ end
36
+
37
+ bbcode = File.read(markdown_file).md_to_bbcode
38
+ if bbcode_file.nil?
39
+ puts bbcode
40
+ else
41
+ File.write(bbcode_file, bbcode)
42
+ end
@@ -0,0 +1,61 @@
1
+ require 'md_to_bbcode/core_extensions/string/md_to_bbcode'
2
+
3
+ module MdToBbcode
4
+
5
+ # Convert a Markdown string to Bbcode
6
+ #
7
+ # Parameters::
8
+ # * *markdown* (String): The Markdown string
9
+ # Result::
10
+ # * String: BBCode converted string
11
+ def self.md_to_bbcode(markdown)
12
+ bbcode_lines = []
13
+ already_in_list = false
14
+ markdown.
15
+ # Images (do this gsub before links and any single tags, like bold, headings...)
16
+ gsub(/!\[(.*?)\]\((.*?)\)/, '[img]\2[/img]').
17
+ # Links
18
+ gsub(/\[(.*?)\]\((.*?)\)/, '[url=\2]\1[/url]').
19
+ # Bold
20
+ gsub(/\*\*(.*?)\*\*/m, '[b]\1[/b]').
21
+ # Heading 1
22
+ gsub(/^# (.*?)$/, '[size=6][b]\1[/b][/size]').
23
+ # Heading 2
24
+ gsub(/^## (.*?)$/, '[size=6]\1[/size]').
25
+ # Heading 3
26
+ gsub(/^### (.*?)$/, '[size=5][b]\1[/b][/size]').
27
+ # Heading 4
28
+ gsub(/^#### (.*?)$/, '[size=5]\1[/size]').
29
+ # Code blocks (do this before in-line code)
30
+ gsub(/```(.*?)\n(.*?)```/m, "[code]\\2[/code]").
31
+ # In-line code
32
+ gsub(/`(.*?)`/, '[b][font=Courier New]\1[/font][/b]').
33
+ # Perform lists transformations
34
+ split("\n").each do |line|
35
+ if line =~ /^\* (.+)$/
36
+ # Single bullet line
37
+ bbcode_lines << '[list]' unless already_in_list
38
+ bbcode_lines << "[*]#{$1}"
39
+ already_in_list = true
40
+ elsif line =~ /^\d\. (.+)$/
41
+ # Single numbered line
42
+ bbcode_lines << '[list=1]' unless already_in_list
43
+ bbcode_lines << "[*]#{$1}"
44
+ already_in_list = true
45
+ else
46
+ if already_in_list && !(line =~ /^ (.*)$/)
47
+ bbcode_lines << '[/list]'
48
+ already_in_list = false
49
+ end
50
+ bbcode_lines << line
51
+ end
52
+ end
53
+ bbcode_lines << '[/list]' if already_in_list
54
+ bbcode_lines << '' if markdown.end_with?("\n")
55
+ bbcode_lines.join("\n")
56
+ end
57
+
58
+ end
59
+
60
+ # Add the functionality to the String class
61
+ String.include MdToBbcode::CoreExtensions::String::MdToBbcode
@@ -0,0 +1,23 @@
1
+ module MdToBbcode
2
+
3
+ module CoreExtensions
4
+
5
+ module String
6
+
7
+ module MdToBbcode
8
+
9
+ # Convert a string representation of self from Markdown to Bbcode
10
+ #
11
+ # Result::
12
+ # * String: BBCode converted text
13
+ def md_to_bbcode
14
+ ::MdToBbcode.md_to_bbcode(self.to_s)
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,5 @@
1
+ module MdToBbcode
2
+
3
+ VERSION = '1.0.0'
4
+
5
+ end
@@ -0,0 +1,261 @@
1
+ describe MdToBbcode do
2
+
3
+ it 'converts heading 1' do
4
+ expect('# Heading 1'.md_to_bbcode).to eq '[size=6][b]Heading 1[/b][/size]'
5
+ end
6
+
7
+ it 'converts heading 2' do
8
+ expect('## Heading 2'.md_to_bbcode).to eq '[size=6]Heading 2[/size]'
9
+ end
10
+
11
+ it 'converts heading 3' do
12
+ expect('### Heading 3'.md_to_bbcode).to eq '[size=5][b]Heading 3[/b][/size]'
13
+ end
14
+
15
+ it 'converts heading 4' do
16
+ expect('#### Heading 4'.md_to_bbcode).to eq '[size=5]Heading 4[/size]'
17
+ end
18
+
19
+ it 'converts bold text' do
20
+ expect('**Bold text**'.md_to_bbcode).to eq '[b]Bold text[/b]'
21
+ end
22
+
23
+ it 'converts links' do
24
+ expect('[Link text](https://my.domain.com/path)'.md_to_bbcode).to eq '[url=https://my.domain.com/path]Link text[/url]'
25
+ end
26
+
27
+ it 'converts inline code' do
28
+ expect('`in-line code`'.md_to_bbcode).to eq '[b][font=Courier New]in-line code[/font][/b]'
29
+ end
30
+
31
+ it 'converts images' do
32
+ expect('![Image text](https://my.domain.com/image.jpg)'.md_to_bbcode).to eq '[img]https://my.domain.com/image.jpg[/img]'
33
+ end
34
+
35
+ it 'converts bold text on several lines' do
36
+ md = <<~EOS
37
+ **Bold
38
+ text
39
+ on
40
+ multi-line**
41
+ EOS
42
+ expect(md.md_to_bbcode).to eq(<<~EOS)
43
+ [b]Bold
44
+ text
45
+ on
46
+ multi-line[/b]
47
+ EOS
48
+ end
49
+
50
+ it 'converts bullets list' do
51
+ md = <<~EOS
52
+ * List item 1
53
+ * List item 2
54
+ * List item 3
55
+ EOS
56
+ expect(md.md_to_bbcode).to eq(<<~EOS)
57
+ [list]
58
+ [*]List item 1
59
+ [*]List item 2
60
+ [*]List item 3
61
+ [/list]
62
+ EOS
63
+ end
64
+
65
+ it 'converts numbered list' do
66
+ md = <<~EOS
67
+ 1. List item 1
68
+ 2. List item 2
69
+ 3. List item 3
70
+ EOS
71
+ expect(md.md_to_bbcode).to eq(<<~EOS)
72
+ [list=1]
73
+ [*]List item 1
74
+ [*]List item 2
75
+ [*]List item 3
76
+ [/list]
77
+ EOS
78
+ end
79
+
80
+ it 'converts multi-line numbered list' do
81
+ md = <<~EOS
82
+ 1. List item 1
83
+ And another line 1
84
+
85
+ 2. List item 2
86
+ And another line 2
87
+
88
+ 3. List item 3
89
+ And another line 3
90
+ EOS
91
+ expect(md.md_to_bbcode).to eq(<<~EOS)
92
+ [list=1]
93
+ [*]List item 1
94
+ And another line 1
95
+
96
+ [*]List item 2
97
+ And another line 2
98
+
99
+ [*]List item 3
100
+ And another line 3
101
+ [/list]
102
+ EOS
103
+ end
104
+
105
+ it 'converts code blocks' do
106
+ md = <<~EOS
107
+ ```ruby
108
+ def hello
109
+ puts 'Hello world'
110
+ end
111
+ hello
112
+ $stdin.gets
113
+ ```
114
+ EOS
115
+ expect(md.md_to_bbcode).to eq(<<~EOS)
116
+ [code]def hello
117
+ puts 'Hello world'
118
+ end
119
+ hello
120
+ $stdin.gets
121
+ [/code]
122
+ EOS
123
+ end
124
+
125
+ it 'converts a whole text mixing markups' do
126
+ md = <<~EOS
127
+ # Heading h1
128
+
129
+ Normal text
130
+
131
+ **Bold text**
132
+
133
+ Not bold followed by **bold and followed by** not bold.
134
+
135
+ Not bold followed by **bold and
136
+ followed
137
+ by** not bold on multi-lines.
138
+
139
+ **Bold text including a [link to Google](https://www.google.com).**
140
+
141
+ This is a bullet list:
142
+ * Bullet item 1
143
+ * Bullet item 2
144
+ * Bullet item 3
145
+
146
+ ## Heading h2
147
+
148
+ Here is a link to [Google](https://www.google.com/) in a middle of a line.
149
+
150
+ An inline code block `this is code` to be inserted.
151
+
152
+ ### Heading h3
153
+
154
+ #### Heading h4 with `embedded code`
155
+
156
+ Here is a code block in json:
157
+ ```json
158
+ {
159
+ "my_json": {
160
+ "is": "super",
161
+ "great": "and",
162
+ "useful": true
163
+ }
164
+ }
165
+ ```
166
+
167
+ This is a numbered list:
168
+ 1. Numbered item 1
169
+ 2. Numbered item 2
170
+ 3. Numbered item 3
171
+
172
+ This is a numbered list with 1 item:
173
+ 1. Numbered item 1
174
+
175
+ This is a numbered list multi-line:
176
+ 1. Numbered item 1
177
+ Additional content 1
178
+ 2. Numbered item 2
179
+ Additional content 2
180
+
181
+ 3. Numbered item 3
182
+ Additional content 3
183
+
184
+ Here is an inserted image:
185
+ ![Example of image](https://x-aeon.com/muriel.jpg)
186
+
187
+ And ending text
188
+ EOS
189
+ expect(md.md_to_bbcode).to eq(<<~EOS)
190
+ [size=6][b]Heading h1[/b][/size]
191
+
192
+ Normal text
193
+
194
+ [b]Bold text[/b]
195
+
196
+ Not bold followed by [b]bold and followed by[/b] not bold.
197
+
198
+ Not bold followed by [b]bold and
199
+ followed
200
+ by[/b] not bold on multi-lines.
201
+
202
+ [b]Bold text including a [url=https://www.google.com]link to Google[/url].[/b]
203
+
204
+ This is a bullet list:
205
+ [list]
206
+ [*]Bullet item 1
207
+ [*]Bullet item 2
208
+ [*]Bullet item 3
209
+ [/list]
210
+
211
+ [size=6]Heading h2[/size]
212
+
213
+ Here is a link to [url=https://www.google.com/]Google[/url] in a middle of a line.
214
+
215
+ An inline code block [b][font=Courier New]this is code[/font][/b] to be inserted.
216
+
217
+ [size=5][b]Heading h3[/b][/size]
218
+
219
+ [size=5]Heading h4 with [b][font=Courier New]embedded code[/font][/b][/size]
220
+
221
+ Here is a code block in json:
222
+ [code]{
223
+ "my_json": {
224
+ "is": "super",
225
+ "great": "and",
226
+ "useful": true
227
+ }
228
+ }
229
+ [/code]
230
+
231
+ This is a numbered list:
232
+ [list=1]
233
+ [*]Numbered item 1
234
+ [*]Numbered item 2
235
+ [*]Numbered item 3
236
+ [/list]
237
+
238
+ This is a numbered list with 1 item:
239
+ [list=1]
240
+ [*]Numbered item 1
241
+ [/list]
242
+
243
+ This is a numbered list multi-line:
244
+ [list=1]
245
+ [*]Numbered item 1
246
+ Additional content 1
247
+ [*]Numbered item 2
248
+ Additional content 2
249
+
250
+ [*]Numbered item 3
251
+ Additional content 3
252
+ [/list]
253
+
254
+ Here is an inserted image:
255
+ [img]https://x-aeon.com/muriel.jpg[/img]
256
+
257
+ And ending text
258
+ EOS
259
+ end
260
+
261
+ end
@@ -0,0 +1,4 @@
1
+ require 'md_to_bbcode'
2
+
3
+ module MdToBbcodeTest
4
+ end
@@ -0,0 +1,102 @@
1
+ require 'md_to_bbcode_test.rb'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18
+ RSpec.configure do |config|
19
+ # rspec-expectations config goes here. You can use an alternate
20
+ # assertion/expectation library such as wrong or the stdlib/minitest
21
+ # assertions if you prefer.
22
+ config.expect_with :rspec do |expectations|
23
+ # This option will default to `true` in RSpec 4. It makes the `description`
24
+ # and `failure_message` of custom matchers include text for helper methods
25
+ # defined using `chain`, e.g.:
26
+ # be_bigger_than(2).and_smaller_than(4).description
27
+ # # => "be bigger than 2 and smaller than 4"
28
+ # ...rather than:
29
+ # # => "be bigger than 2"
30
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
31
+ end
32
+
33
+ # rspec-mocks config goes here. You can use an alternate test double
34
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
35
+ config.mock_with :rspec do |mocks|
36
+ # Prevents you from mocking or stubbing a method that does not exist on
37
+ # a real object. This is generally recommended, and will default to
38
+ # `true` in RSpec 4.
39
+ mocks.verify_partial_doubles = true
40
+ end
41
+
42
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
43
+ # have no way to turn it off -- the option exists only for backwards
44
+ # compatibility in RSpec 3). It causes shared context metadata to be
45
+ # inherited by the metadata hash of host groups and examples, rather than
46
+ # triggering implicit auto-inclusion in groups with matching metadata.
47
+ config.shared_context_metadata_behavior = :apply_to_host_groups
48
+
49
+ # The settings below are suggested to provide a good initial experience
50
+ # with RSpec, but feel free to customize to your heart's content.
51
+ =begin
52
+ # This allows you to limit a spec run to individual examples or groups
53
+ # you care about by tagging them with `:focus` metadata. When nothing
54
+ # is tagged with `:focus`, all examples get run. RSpec also provides
55
+ # aliases for `it`, `describe`, and `context` that include `:focus`
56
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
57
+ config.filter_run_when_matching :focus
58
+
59
+ # Allows RSpec to persist some state between runs in order to support
60
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
61
+ # you configure your source control system to ignore this file.
62
+ config.example_status_persistence_file_path = "spec/examples.txt"
63
+
64
+ # Limits the available syntax to the non-monkey patched syntax that is
65
+ # recommended. For more details, see:
66
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
67
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
68
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
69
+ config.disable_monkey_patching!
70
+
71
+ # This setting enables warnings. It's recommended, but in some cases may
72
+ # be too noisy due to issues in dependencies.
73
+ config.warnings = true
74
+
75
+ # Many RSpec users commonly either run the entire suite or an individual
76
+ # file, and it's useful to allow more verbose output when running an
77
+ # individual spec file.
78
+ if config.files_to_run.one?
79
+ # Use the documentation formatter for detailed output,
80
+ # unless a formatter has already been configured
81
+ # (e.g. via a command-line flag).
82
+ config.default_formatter = "doc"
83
+ end
84
+
85
+ # Print the 10 slowest examples and example groups at the
86
+ # end of the spec run, to help surface which specs are running
87
+ # particularly slow.
88
+ config.profile_examples = 10
89
+
90
+ # Run specs in random order to surface order dependencies. If you find an
91
+ # order dependency and want to debug it, you can fix the order by providing
92
+ # the seed, which is printed after each run.
93
+ # --seed 1234
94
+ config.order = :random
95
+
96
+ # Seed global randomization in this process using the `--seed` CLI option.
97
+ # Setting this allows you to use `--seed` to deterministically reproduce
98
+ # test failures related to randomization by passing the same `--seed` value
99
+ # as the one that triggered the failure.
100
+ Kernel.srand config.seed
101
+ =end
102
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: md_to_bbcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Muriel Salvan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Provides an API and an executable to convert Markdown text to BBCode
28
+ format
29
+ email:
30
+ - muriel@x-aeon.com
31
+ executables:
32
+ - md_to_bbcode
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - bin/md_to_bbcode
37
+ - lib/md_to_bbcode.rb
38
+ - lib/md_to_bbcode/core_extensions/string/md_to_bbcode.rb
39
+ - lib/md_to_bbcode/version.rb
40
+ - spec/api_spec.rb
41
+ - spec/md_to_bbcode_test.rb
42
+ - spec/spec_helper.rb
43
+ homepage: https://github.com/Muriel-Salvan/md_to_bbcode
44
+ licenses:
45
+ - BSD-3-Clause
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.1.2
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Convert Markdown text to Bbcode
66
+ test_files: []