simple_faq 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8583a32c2dc20e46fe8fb78d56160a45e3fc55a7
4
+ data.tar.gz: 3825cd3d87edeb51318b412994a469812e700a2c
5
+ SHA512:
6
+ metadata.gz: edce073f178e945935797e58c09444ab9252cf0a6cb6f8aae3eb3bf4f91be3d6f317acc8c41b7eceaa1c29f3cfdd7b2b98ed78c39e46e631b3f93e5dc703b1a2
7
+ data.tar.gz: 8b393d84f1a188de6bd163547fa71f493b0e76ba26ea68d0e65e9a8dfe62525958d481340473cc3d84d32dd2cfe6b710067726f273ade1cb6ad7f6156de10815
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Andrei Andreev
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # SimpleFAQ
2
+
3
+ FAQ documents often contain multiple sections with groups of questions and answers, which may get hard to maintain in HTML format.
4
+
5
+ SimpleFAQ makes it easy to create interactive FAQ documents using Markdown and a few special tags.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'simple_faq'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install simple_faq
22
+
23
+
24
+ ### CSS and JS Assets
25
+
26
+ If you are using this as a Rails gem, require the gem assets:
27
+
28
+ ~~~
29
+ // app/assets/javascripts/application.js:
30
+ //= require simple_faq
31
+
32
+ // app/assets/stylesheets/application.css:
33
+ *= require simple_faq
34
+ ~~~
35
+
36
+ If you are not using rails, copy the assets files manually.
37
+
38
+ ## Usage
39
+
40
+ ~~~ruby
41
+ html_for_display = SimpleFAQ::Formatter.new(markdown_with_faq_tags).html
42
+ ~~~
43
+
44
+ ### FAQ Tags:
45
+
46
+ Question and answer tag pairs work together:
47
+
48
+ {q}Question title{/q} <= will display the title as a link
49
+ {a}Answer content{/a} <= clicking the title (above) of this question
50
+ will expand/collapse its answer
51
+
52
+ and may be displayed in sections:
53
+
54
+ {section-list} <= will display a list of section titles,
55
+ each linking to the corresponding section
56
+ down the page
57
+
58
+ {section-title}Section 1{/section-title}
59
+ {q}Question title{/q}
60
+ {a}Answer content, in Markdown{/a}
61
+
62
+ {section-title}Section 2{/section-title}
63
+ {q}Question title{/q}
64
+ {a}Answer content{/a}
65
+
66
+ ### Example:
67
+
68
+ In a Rails view:
69
+
70
+ <%
71
+
72
+ faq_content = %Q{
73
+ #Intro Headline
74
+
75
+ {section-list}
76
+
77
+ {section-title}Section 1{/section-title}
78
+
79
+ {q}How do I create a new paragraph in HTML?{/q}
80
+ {a}
81
+ Use the `p` tag:
82
+
83
+ ~~~
84
+ <p>Paragraph</p>
85
+ ~~~
86
+ {/a}
87
+
88
+ {q}Can you help me feel better?{/q}
89
+ {a}Take a short walk, that almost always helps. If you are thirsty or hungry, have some water or food. If you're tired, rest for a bit.
90
+
91
+ ### Or, watch some kittens.
92
+
93
+ {vimeo:11663853}
94
+ {/a}
95
+
96
+ {section-title}Section 2{/section-title}
97
+
98
+ {q}Section 2 Q1{/q}
99
+ {a}Section 2 A1{/a}
100
+
101
+ {q}I would like some more kittens, this time with close-ups!{/q}
102
+ {a}
103
+ Here you go:
104
+
105
+ {vimeo:23607676}
106
+ {/a}
107
+ }
108
+
109
+ formatted_faq_content = SimpleFAQ::Formatter.new(faq_content).html
110
+ %>
111
+
112
+ <%= formatted_faq_content.html_safe %>
113
+
114
+ In a real application, you may want to have the faq content in a database and prepare the formatted_faq_content in the model.
115
+
116
+ ## Contributing
117
+
118
+ 1. Fork it ( https://github.com/[my-github-username]/faq_format/fork )
119
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
120
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
121
+ 4. Push to the branch (`git push origin my-new-feature`)
122
+ 5. Create a new Pull Request
@@ -0,0 +1,11 @@
1
+ $(document).ready(function(){
2
+
3
+ // toggle answer
4
+ $('[data-qa]').click(function(el){
5
+ var questionID = $(this).data('qa');
6
+ // uncomment to hide all other answers when showing the selected one
7
+ // $('.faq--answer').not('.answer-' + questionID).addClass('hidden');
8
+ $('.answer-' + questionID).toggle();
9
+ })
10
+
11
+ })
@@ -0,0 +1,128 @@
1
+ // FAQFormatter Styles
2
+
3
+ .faq--section-title {
4
+ text-transform: uppercase;
5
+ font-size: 1em;
6
+ border: 1px solid #3c6;
7
+ display: inline-block;
8
+ padding: 0.3em 0.7em;
9
+ border-radius: 3px;
10
+ background-color: #f6fff6;
11
+ color: #062;
12
+ font-weight: bold;
13
+ }
14
+
15
+
16
+ .faq--question {
17
+ font-size: 1.1em;
18
+ color: #c60;
19
+ cursor: pointer;
20
+ // margin: .4em 0;
21
+ margin: 0 0 0 1.8em;
22
+ padding: 4px 0;
23
+
24
+ & span.with-video {
25
+ &:before {
26
+ content: "video";
27
+ text-transform: uppercase;
28
+ font-size: 10px;
29
+ background-color: #fff;
30
+ color: #c60;
31
+ padding: 2px 4px;
32
+ font-weight: normal;
33
+ margin-left: 1em;
34
+ border: 1px solid #c60;
35
+ border-radius: 3px;
36
+ }
37
+
38
+ }
39
+
40
+ &:hover {
41
+ color: #b50;
42
+ background-color: lighten(#b50,60%)
43
+ }
44
+
45
+ &:before {
46
+ content: "Q: ";
47
+ font-size: 1.1em;
48
+ margin-left: -25px;
49
+ margin-top: -3px;
50
+ }
51
+ }
52
+
53
+ .faq--answer {
54
+ padding: 0 0 0 .3em;
55
+ margin: 0 0 0 1.8em;
56
+
57
+ &.hidden { display:none; }
58
+
59
+ & > p {
60
+ margin: 0 0 .7em 0;
61
+ font-size: 1.1em;
62
+ line-height: 1.35;
63
+ }
64
+
65
+
66
+ &:before {
67
+ content: "A:";
68
+
69
+ font-size: 1.15em;
70
+ margin-left: -25px;
71
+ font-weight: bold;
72
+ position: absolute;
73
+ }
74
+
75
+ }
76
+
77
+ .faq--section--title-link {
78
+ font-size: 1.3em;
79
+ font-weight: normal;
80
+ line-height: 1.4;
81
+ > a:hover {
82
+ color: #333;
83
+ background-color: #fff;
84
+ }
85
+ & > a {
86
+ color: #666;
87
+ text-decoration: none;
88
+ }
89
+ }
90
+
91
+ .faq--section--title-link:last-child {
92
+ margin-bottom: 2em;
93
+ }
94
+
95
+ .faq--section--title-anchor {
96
+ color: #666;
97
+ font-size: 1.7em;
98
+ font-weight: normal;
99
+ margin-top: 1em;
100
+ margin-bottom: 0.3em;
101
+ }
102
+
103
+
104
+ .faq {
105
+
106
+ font-family: arial, helvetica, sans-serif;
107
+ font-size: 1rem;
108
+ color: #433;
109
+
110
+
111
+ code, pre {
112
+ background-color: #eee;
113
+ padding: 0px 4px;
114
+ outline: 1px solid #ddd;
115
+ font-size: .95em;
116
+
117
+ & > code {
118
+ outline: none;
119
+ }
120
+ }
121
+
122
+ ol, li {
123
+ & > p {
124
+ margin: 0;
125
+ }
126
+
127
+ }
128
+ }
data/lib/simple_faq.rb ADDED
@@ -0,0 +1,119 @@
1
+ require "simple_faq/version"
2
+ require 'simple_faq/engine' if defined?(Rails)
3
+ require "redcarpet"
4
+
5
+ module SimpleFAQ
6
+
7
+ class Formatter
8
+
9
+ REGEXES = {
10
+ section_title: /(\{section-title\}([\s|\S|\n|\r]*?)\{\/section-title\})/i,
11
+ intro: /\A([\s|\S]*?){/i,
12
+ qa: /(\{q\}([\s\S]*?)\{\/q\}[\r\n|\n|\s]*?\{a\}([\s\S]*?)\{\/a\})/i,
13
+ vimeo: /(\{\s*?vimeo\s*?:\s*?([0-9]*?)\s*?\})/i,
14
+ has_video: /({[\s]*?vimeo\s*?:\s*?\d{5,10}\s*?})/i
15
+ }
16
+
17
+ MARKDOWN = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
18
+ no_intra_emphasis: true, tables: true,
19
+ fenced_code_blocks: true, autolink: true,
20
+ strikethrough: true, highlight: true, quote: true)
21
+
22
+ FORMATTING = {
23
+ q: "<h3 class=\"faq--question\" data-qa=\"{i}\">{q}</h3>",
24
+ q_with_video: "<h3 class=\"faq--question\" data-qa=\"{i}\">{q}<span class=\"with-video\"></span></h3>",
25
+ a: "<div class=\"faq--answer answer-{i} hidden\">{a}</div>",
26
+ vimeo: '<iframe src="//player.vimeo.com/video/{stream_id}?title=0&amp;byline=0&amp;portrait=0&amp;badge=0" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
27
+ section_list: '<ul class="faq--section--list">{section-list}</ul>',
28
+ title_anchor: "<h2 class=\"faq--section--title-anchor\"><a name=\"section-{i}\"></a>{title}</h2>",
29
+ title_link: "<li class=\"faq--section--title-link\"><a href=\"#section-{i}\">{title}</a></li>",
30
+ body_wrap: %Q{<div class="faq">{body}</div>}
31
+ }
32
+
33
+ def initialize(body)
34
+ @body = body.strip.gsub("\r", "")
35
+ @section_list = ""
36
+ format_section_titles
37
+ format_qa_pairs
38
+ format_intro
39
+ format_section_list
40
+ @body.gsub!(/(\n){1,}/, "\n")
41
+ end
42
+
43
+ def html
44
+ FORMATTING[:body_wrap].sub("{body}", @body)
45
+ end
46
+
47
+ private
48
+
49
+ def format_section_list
50
+ @body.gsub!('{section-list}', FORMATTING[:section_list].sub("{section-list}", @section_list))
51
+ end
52
+
53
+ def format_section_titles
54
+ title_matches = @body.scan(REGEXES[:section_title])
55
+ title_matches.each_with_index do |title_match, i|
56
+ title_sub_string = title_match[0]
57
+ title = title_match[1]
58
+
59
+ title_anchor = FORMATTING[:title_anchor].gsub('{i}', i.to_s).gsub('{title}', title)
60
+ title_link = FORMATTING[:title_link].gsub('{i}', i.to_s).gsub('{title}', title)
61
+
62
+ @body.sub!(title_sub_string, title_anchor)
63
+ @section_list << title_link
64
+ end
65
+ end
66
+
67
+ def format_qa_pairs
68
+ qas = @body.scan(REGEXES[:qa])
69
+ qas.each_with_index do |qa_pair, qa_index|
70
+ qa_sub_string = qa_pair[0]
71
+ q = qa_pair[1]
72
+ a = qa_pair[2]
73
+ q_formatting = if a.match(REGEXES[:has_video])
74
+ :q_with_video
75
+ else
76
+ :q
77
+ end
78
+
79
+ qa_id = "q#{qa_index}"
80
+
81
+ a_with_markdown = MARKDOWN.render(a.strip)
82
+ a_with_vimeo = process_vimeo_tags(a_with_markdown)
83
+
84
+ q_formatted = FORMATTING[q_formatting].gsub('{q}', q.strip).gsub('{i}', qa_id)
85
+ a_formatted = FORMATTING[:a].gsub('{a}', a_with_vimeo).gsub('{i}', qa_id)
86
+
87
+ qa_html = q_formatted + "\n" + a_formatted
88
+
89
+ @body.sub!(qa_sub_string, qa_html)
90
+ end
91
+
92
+ end
93
+
94
+ def process_vimeo_tags s
95
+ r = s.dup
96
+ streams = s.scan(REGEXES[:vimeo])
97
+
98
+ streams.each do |stream|
99
+ stream_tag = stream[0]
100
+ stream_id = stream[1]
101
+ stream_html = FORMATTING[:vimeo].sub('{stream_id}', stream_id)
102
+ r.sub!(stream_tag, stream_html)
103
+ end
104
+ r
105
+ end
106
+
107
+ def format_intro
108
+ intro_tag_match = @body.scan(REGEXES[:intro]).flatten
109
+ return unless intro_tag_match.size > 0
110
+
111
+ intro_sub_string = intro_tag_match[0]
112
+ intro_body = intro_sub_string.strip
113
+
114
+ @body.sub!(intro_sub_string, MARKDOWN.render(intro_body))
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,6 @@
1
+ module SimpleFAQ
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleFAQ
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_faq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrei Andreev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redcarpet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ - aaandre@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - LICENSE.txt
105
+ - README.md
106
+ - app/assets/javascripts/simple_faq.js
107
+ - app/assets/stylesheets/simple_faq.scss
108
+ - lib/simple_faq.rb
109
+ - lib/simple_faq/engine.rb
110
+ - lib/simple_faq/version.rb
111
+ homepage: https://github.com/andreimoment/simple_faq
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.4.6
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Easily create FAQ documents using Markdown and a few specilaized tags.
135
+ test_files: []