Module: Howzit::ConditionalContent
- Defined in:
- lib/howzit/conditional_content.rb
Overview
Conditional Content processor Handles @if/@unless/@end blocks in topic content
Class Method Summary collapse
-
.process(content, context = {}) ⇒ String
Process conditional blocks in content.
Class Method Details
.process(content, context = {}) ⇒ String
Process conditional blocks in content
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/howzit/conditional_content.rb', line 16 def process(content, context = {}) lines = content.split(/\n/) output = [] condition_stack = [] # Track if any condition in the current chain has been true # This is used for @elsif and @else to know if a previous branch matched chain_matched_stack = [] lines.each do |line| # Check for @if or @unless if line =~ /^@(if|unless)\s+(.+)$/i directive = Regexp.last_match(1).downcase condition = Regexp.last_match(2).strip # Evaluate condition result = ConditionEvaluator.evaluate(condition, context) # For @unless, negate the result result = !result if directive == 'unless' condition_stack << result chain_matched_stack << result # Don't include the @if/@unless line itself next end # Check for @elsif if line =~ /^@elsif\s+(.+)$/i condition = Regexp.last_match(1).strip # If previous condition in chain was true, this branch is false # Otherwise, evaluate the condition if !condition_stack.empty? && chain_matched_stack.last # Previous branch matched, so this one is false condition_stack[-1] = false else # Previous branch didn't match, evaluate this condition result = ConditionEvaluator.evaluate(condition, context) condition_stack[-1] = result chain_matched_stack[-1] = result if result end # Don't include the @elsif line itself next end # Check for @else if line =~ /^@else\s*$/i # If any previous condition in chain was true, this branch is false # Otherwise, this branch is true if !condition_stack.empty? && chain_matched_stack.last # Previous branch matched, so else is false condition_stack[-1] = false else # No previous branch matched, so else is true condition_stack[-1] = true chain_matched_stack[-1] = true end # Don't include the @else line itself next end # Check for @end - only skip if it's closing an @if/@unless/@elsif/@else block if (line =~ /^@end\s*$/) && !condition_stack.empty? # This @end closes a conditional block, so skip it condition_stack.pop chain_matched_stack.pop next end # Otherwise, this @end is for @before/@after, so include it # Include the line only if all conditions in stack are true output << line if condition_stack.all? { |cond| cond } end output.join("\n") end |