# frozen_string_literal: true module Bridgetown module Filters # The following set of code was *adapted* from `Liquid::If` # ref: https://git.io/vp6K6 module ConditionHelpers # Parse a string to a Liquid Condition def parse_condition(exp) parser = Liquid::Parser.new(exp) condition = parse_binary_comparison(parser) parser.consume(:end_of_string) condition end # Generate a Liquid::Condition object from a Liquid::Parser object additionally processing # the parsed expression based on whether the expression consists of binary operations with # Liquid operators `and` or `or` # # @param parser [Liquid::Parser] # @return [Liquid::Condition] def parse_binary_comparison(parser) condition = parse_comparison(parser) first_condition = condition while (binary_operator = parser.id?("and") || parser.id?("or")) child_condition = parse_comparison(parser) condition.send(binary_operator, child_condition) condition = child_condition end first_condition end # Generates a Liquid::Condition object from a Liquid::Parser object based # on whether the parsed expression involves a "comparison" operator # (e.g. <, ==, >, !=, etc) # # @param parser [Liquid::Parser] # @return [Liquid::Condition] def parse_comparison(parser) left_operand = Liquid::Expression.parse(parser.expression) operator = parser.consume?(:comparison) # No comparison-operator detected. Initialize a Liquid::Condition using only left operand return Liquid::Condition.new(left_operand) unless operator # Parse what remained after extracting the left operand and the `:comparison` operator # and initialize a Liquid::Condition object using the operands and the comparison-operator Liquid::Condition.new(left_operand, operator, Liquid::Expression.parse(parser.expression)) end end end end