faqml 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,51 +1,46 @@
1
1
  # FML
2
2
 
3
- The FAQ Markup Language. It's pretty simple. The gem is called `faqml`, so first install it.
3
+ The FAQ Markup Language. It's pretty simple. The gem is called `faqml`, so first install it. Then just access it through Tilt.
4
4
 
5
5
  ```ruby
6
6
  require 'rubygems'
7
7
  require 'faqml'
8
- data = File.readlines('mypage.fml').join()
9
- puts FML.new(data).to_html
8
+ require 'tilt'
9
+ puts Tilt.new('mypage.fml').render
10
10
  ```
11
11
 
12
- Your markup in `mypage.fml` should be valid markdown. The only difference is, that QnA blocks are started by three dashes (`---`), and questions and answers are seperated by three equals (`===`). The first line of the question block will be the QnA's title. That's all.
12
+ Your markup in `mypage.fml` should be valid markdown. The only difference is, that QnA blocks are started by the keyword "question:", or "Q:", and answers being with "answer:" or "A:". If there is any text on the line after the question or answer keywords, it will be that section's summary (neither are required). All remaining indented text consitute the body of the question of answer.
13
13
 
14
14
  This FML
15
15
 
16
16
  ```fml
17
- ---
18
- What kind of Bear is Best?
19
- I hear there are basically two school of thought.
20
- ===
21
- False. *Blackbear*.
22
-
23
- ---
24
- Do Bears eat Beats?
25
- ===
26
- Of course.
17
+ question: What kind of Bear is Best?
18
+ I hear there are basically two school of thought.
19
+ answer:
20
+ False. *Blackbear*.
21
+
22
+ Q: Do Bears eat Beats?
23
+ A: Of course.
27
24
  ```
28
25
 
29
26
  Produces this HTML
30
27
 
31
28
  ```html
32
29
  <section class="qna">
33
- <h1><a href="#">What kind of Bear is Best?</a></h1>
34
- <div class="qna">
35
- <div class="question">
36
- <p>I hear there are basically two school of thought.</p>
37
- </div>
38
- <div class="answer">
39
- <p>False. <em>Blackbear</em>.</p>
40
- </div>
41
- </div>
30
+ <details class="question" open>
31
+ <summary>What kind of Bear is Best?</summary>
32
+ <div>I hear there are basically two school of thought</div>
33
+ <details class="answer" open>
34
+ <div>False. *Blackbear*</div>
35
+ </details>
36
+ </details>
42
37
  </section>
43
38
  <section class="qna">
44
- <h1><a href="#">Do Bears eat Beats?</a></h1>
45
- <div class="qna">
46
- <div class="answer">
47
- <p>Of course.</p>
48
- </div>
49
- </div>
39
+ <details class="question" open>
40
+ <summary>Do Bears eat Beats?</summary>
41
+ <details class="answer" open>
42
+ <summary>Of course.</summary>
43
+ </details>
44
+ </details>
50
45
  </section>
51
46
  ```
data/lib/faqml.rb CHANGED
@@ -4,5 +4,10 @@
4
4
  require 'temple'
5
5
  require 'fml/version'
6
6
  require 'fml/parser'
7
+ require 'fml/wrap_filter'
8
+ require 'fml/details_filter'
7
9
  require 'fml/engine'
8
10
  require 'fml/template'
11
+
12
+ # module FAQML;end; require 'pp'; require 'temple'; %w{parser details_filter wrap_filter engine template}.each {|x| require "./lib/fml/#{x}"}
13
+ # puts Tilt.new('test/test0.fml').render
@@ -0,0 +1,34 @@
1
+ class FAQML::DetailsFilter < Temple::Filter
2
+ def initialize(options = {})
3
+ @options = options
4
+ end
5
+
6
+ def call(exp)
7
+ compile(exp)
8
+ end
9
+
10
+ def on_fml_qna(question, answer=nil)
11
+ answer_sexp = !answer.nil? && answer.length >= 4 ? build_fml_details('answer', answer[2], answer[3]) : nil
12
+ question_sexp = build_fml_details('question', question[2], question[3])
13
+ question_sexp.last << answer_sexp unless answer_sexp.nil?
14
+ [:html, :tag, 'section', [:html, :attrs, [:html, :attr, 'class', [:static, 'qna']]],
15
+ question_sexp
16
+ ]
17
+ end
18
+
19
+ private
20
+
21
+ def build_fml_details(class_name, summary, details)
22
+ sexp = [:html, :tag, 'details',
23
+ [:html, :attrs,
24
+ [:html, :attr, 'class', [:static, class_name]]],
25
+ [:multi]]
26
+ if !summary.last.first.nil? && summary.last.first != ''
27
+ sexp.last << [:html, :tag, 'summary', [:multi], [:static, summary.last.first]]
28
+ end
29
+ if details.length > 0
30
+ sexp.last << [:html, :tag, 'div', [:multi], [:multi, *details.last]]
31
+ end
32
+ sexp
33
+ end
34
+ end
data/lib/fml/engine.rb CHANGED
@@ -12,7 +12,8 @@ class FAQML::Engine < Temple::Engine
12
12
 
13
13
  # TODO: replace inline generation with a markdown filter
14
14
  # use FAQML::MarkdownFilter
15
- # use FAQML::WrapFilter
15
+ use FAQML::WrapFilter
16
+ use FAQML::DetailsFilter
16
17
 
17
18
  html :AttributeMerger, :attr_delimiter
18
19
  html :AttributeSorter, :sort_attrs
@@ -0,0 +1,5 @@
1
+ # require 'redcarpet'
2
+
3
+ # renderer = Redcarpet::Render::HTML.new
4
+ # extensions = {fenced_code_blocks: true}
5
+ # @markdown = Redcarpet::Markdown.new(renderer, extensions)
data/lib/fml/parser.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'redcarpet'
2
-
3
1
  # Transforms FML into a Temple expression
4
2
  # @api private
5
3
  class FAQML::Parser
@@ -32,11 +30,6 @@ class FAQML::Parser
32
30
 
33
31
  def initialize(options = {})
34
32
  super
35
-
36
- renderer = Redcarpet::Render::HTML.new
37
- extensions = {fenced_code_blocks: true}
38
- @markdown = Redcarpet::Markdown.new(renderer, extensions)
39
-
40
33
  @tab = ' ' * @options[:tabsize]
41
34
  end
42
35
 
@@ -65,32 +58,18 @@ class FAQML::Parser
65
58
 
66
59
  private
67
60
 
68
- # TODO: the markdown rendering should be a filter... that way
69
- # you could have different kinds of FML markups
70
-
71
- # TODO: rewrite this to have a sort of wrapping filter... have this just output:
72
- # [:question, [:summary, [text]], [:data, [line, line...]]]
73
- # [:answer, [:summary, [text]], [:data, [line, line...]]]
74
-
75
61
  def parse_line
76
62
  # start an answer block
77
63
  if @line =~ /^a(nswer)?(\s*)\:\s*(.*?)$/i
78
64
  asummary = @line.sub(/^a(nswer)?(\s*)\:(\s*)/i, '')
79
65
  syntax_error!("Cannot begin an answer without a question") if @current != :q
80
66
  @current = :a
81
-
82
- @stacks.last.last << [:html, :tag, 'details', [:html, :attrs, [:html, :attr, 'class', [:static, 'answer']]], [:multi]]
83
- @stacks.last.last.last.last << [:html, :tag, 'summary', [:multi], [:static, asummary]]
84
- @stacks.last.last.last.last << [:html, :tag, 'div', [:multi], [:multi]]
67
+ @stacks << [:fml, :answer, [:fml, :summary, [asummary]], [:fml, :details, []] ]
85
68
 
86
69
  elsif @line =~ /^q(uestion)?(\s*)\:\s*(.*?)$/i
87
70
  qsummary = @line.sub(/^q(uestion)?(\s*)\:(\s*)/i, '')
88
71
  @current = :q
89
-
90
- @stacks << [:html, :tag, 'section', [:html, :attrs, [:html, :attr, 'class', [:static, 'qna']]],[:multi]]
91
- @stacks.last.last << [:html, :tag, 'details', [:html, :attrs, [:html, :attr, 'class', [:static, 'question']]], [:multi]]
92
- @stacks.last.last.last.last << [:html, :tag, 'summary', [:multi], [:static, qsummary]]
93
- @stacks.last.last.last.last << [:html, :tag, 'div', [:multi], [:multi]]
72
+ @stacks << [:fml, :question, [:fml, :summary, [qsummary]], [:fml, :details, []]]
94
73
 
95
74
  else
96
75
  indent = get_indent(@line)
@@ -99,16 +78,18 @@ class FAQML::Parser
99
78
  @strip_exp = %r"^\s{#{@base_indent}}"
100
79
  end
101
80
 
102
- if indent >= 1
81
+ if @base_indent > 0 && indent >= @base_indent && !@current.nil?
103
82
  # strip off base_indent from @line
104
- @stacks.last.last.last.last.last.last << [:static, @line.sub("\t", @tab).sub(@strip_exp, '')]
105
- @stacks.last.last.last.last.last.last << [:newline]
106
- else
83
+ @stacks.last.last.last << [:static, @line.sub("\t", @tab).sub(@strip_exp, '')]
84
+ @stacks.last.last.last << [:newline]
85
+ elsif @line.strip != ''
107
86
  # done with the indented block
108
87
  @base_indent = 0
109
- end
88
+ @current = nil
110
89
 
111
- @current = :q if @line.strip != ''
90
+ @stacks << [:static, @line]
91
+ @stacks << [:newline]
92
+ end
112
93
  end
113
94
  end
114
95
 
@@ -142,7 +123,6 @@ class FAQML::Parser
142
123
  args[:line] ||= @line
143
124
  args[:lineno] ||= @lineno
144
125
  args[:column] ||= args[:orig_line] && args[:line] ? args[:orig_line].size - args[:line].size : 0
145
- raise SyntaxError.new(message, options[:file],
146
- args[:orig_line], args[:lineno], args[:column])
126
+ raise SyntaxError.new(message, options[:file], args[:orig_line], args[:lineno], args[:column])
147
127
  end
148
128
  end
data/lib/fml/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module FAQML
2
2
  # @api public
3
- VERSION = '0.1.2'
3
+ VERSION = '0.2.0'
4
4
  end
@@ -0,0 +1,43 @@
1
+ # organizes the FAQs into a wrapped-block layout
2
+ class FAQML::WrapFilter < Temple::Filter
3
+
4
+ class SexpError < StandardError
5
+ end
6
+
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def call(exp)
12
+ compile(exp)
13
+ end
14
+
15
+ def on_multi(*exps)
16
+ result = [:multi]
17
+
18
+ current_block = nil
19
+
20
+ exps.each do |exp|
21
+ exp = compile(exp)
22
+
23
+ if exp.length > 2 && exp[0] == :fml
24
+ case exp[1]
25
+ when :question
26
+ current_block = [:fml, :qna, exp]
27
+ result << current_block
28
+ when :answer
29
+ raise SexpError, "Cannot create an answer without a question" if current_block.nil?
30
+ result.last << exp
31
+ current_block = nil
32
+ else
33
+ result << exp
34
+ end
35
+ next
36
+ end
37
+
38
+ result << exp
39
+ end
40
+
41
+ result
42
+ end
43
+ end
data/test/test0.fml ADDED
@@ -0,0 +1,4 @@
1
+ question: What kind of bear is best?
2
+ Well?
3
+ answer: False
4
+ Blackbear
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faqml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-17 00:00:00.000000000 Z
12
+ date: 2012-08-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redcarpet
@@ -70,10 +70,14 @@ files:
70
70
  - README.markdown
71
71
  - faqml.gemspec
72
72
  - lib/faqml.rb
73
+ - lib/fml/details_filter.rb
73
74
  - lib/fml/engine.rb
75
+ - lib/fml/markdown_filter.rb
74
76
  - lib/fml/parser.rb
75
77
  - lib/fml/template.rb
76
78
  - lib/fml/version.rb
79
+ - lib/fml/wrap_filter.rb
80
+ - test/test0.fml
77
81
  - test/test1.fml
78
82
  homepage: http://rubygems.org/gems/faqml
79
83
  licenses: []