require "liquid" require "jekyll" module Jekyll module FractionaliseFilter def fractionalise(input, limit = 0) input = input.to_s if not input.include? "." # if input is a whole number, just return it return input end if input.split(".").length != 2 # generally when liquid filters fail they just print nothing, so we'll do that too return "" end leading_integer, decimal = input.split(".") decimal = "0.#{decimal}" rational = case decimal # handle common weird cases so that e.g. 0.3 returns "1/3" and not "3/10" or "5404319552844595/18014398509481984" when "0.3", "0.33", "0.333" Rational(1, 3) when "0.6", "0.67", "0.666" Rational(2, 3) else decimal.to_r end if limit != 0 and rational.denominator > limit # apply a maximum size for the denominator to avoid the (imo) much more readable "0.41" becoming "41/100" unless wanted return input end "#{leading_integer != "0" ? "#{leading_integer} " : ""}#{rational.numerator}#{rational.denominator}" end def to_stars(input) input = input.to_i if input <= 0 or input > 5 return "[invalid difficulty value: #{input}. difficulty must be between 0.5 and 5 (inclusive)]" end # the "star" characters are invalid unicode but will render properly on the webpage when using the 'stars' font empty_star, half_star, full_star = "", "", "" out = full_star * input.floor if input.floor != input out += half_star end while out.length != 5 out += empty_star end out end def hours_and_minutes(input, long = true) time = input.to_i.divmod(60) hours, minutes = "h", "m" if long hours = " hour" + (time[0] > 1 ? "s" : "") + " " minutes = " minute" + (time[1] > 1 ? "s" : "") + " " end if time[1] == 0 "#{time[0]}#{hours}" elsif time[0] == 0 "#{time[1]}#{minutes}" else "#{time[0]}#{hours}#{time[1]}#{minutes}" end end end end Liquid::Template.register_filter(Jekyll::FractionaliseFilter)