Created
May 9, 2014 20:30
-
-
Save ethnt/dd49101c5479e6561313 to your computer and use it in GitHub Desktop.
A Ruby script to get the fields needed to build a form for a citation using Citation Styles.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# a script to get the fields necessary to build forms for a citation | |
# using citation styles | |
# to-do: name-parts, date-parts, punctuation (delimiters), comments | |
require 'citeproc' | |
require 'csl/styles' | |
TYPES = [ | |
'article', | |
'article-magazine', | |
'article-newspaper', | |
'article-journal', | |
'bill', | |
'book', | |
'broadcast', | |
'chapter', | |
'dataset', | |
'entry', | |
'entry-dictionary', | |
'entry-encyclopedia', | |
'figure', | |
'graphic', | |
'interview', | |
'legislation', | |
'legal_case', | |
'manuscript', | |
'map', | |
'motion_picture', | |
'musical_score', | |
'pamphlet', | |
'paper-conference', | |
'patent', | |
'post', | |
'post-weblog', | |
'personal_communication', | |
'report', | |
'review', | |
'review-book', | |
'song', | |
'speech', | |
'thesis', | |
'treaty', | |
'webpage' | |
] | |
File.open('output.txt', 'w') do |log| | |
LOG = log | |
CSL::Style.ls.each do |shortname| | |
@csl = CSL::Style.load(shortname) | |
TYPES.each do |type| | |
LOG.puts "#{shortname}: #{type}" | |
def run(options) | |
fields = [] | |
if @csl.methods.include?(:has_bibliography?) && @csl.has_bibliography? | |
@csl.bibliography.layout.each_child do |c| | |
fields << renderable_node(c, options) | |
end | |
else | |
LOG.puts "skipping, no bibliography" | |
end | |
fields | |
end | |
def renderable_node(node, options = {}) | |
# If it's a renderable element and it has a macro, return it. | |
if renderable?(node) | |
if node.methods.include?(:has_macro?) && node.has_macro? | |
variable = node['variable'] || '(no variable)' | |
LOG.puts "#{variable} renderable field and has a macro (#{node.macro['name']}) \n" | |
return node['variable'] | |
else | |
variable = node['variable'] || '(no variable)' | |
LOG.puts "#{variable} renderable field \n" | |
return node['variable'] | |
end | |
elsif node.class == CSL::Style::Choose | |
conditionals = node.find_children('if') | |
conditionals.concat(node.find_children('else-if')) | |
need_else = true | |
conditionals.each do |condition| | |
if matches_conditional_block?(condition, options) | |
need_else = false | |
condition.each_child do |c| | |
renderable_node(c, options) | |
end | |
end | |
end | |
if need_else | |
else_block = node.find_child('else') | |
unless else_block.nil? | |
else_block.each_child do |c| | |
renderable_node(c, options) | |
end | |
end | |
end | |
elsif node.class == CSL::Style::Group | |
unless node.nil? | |
node.each_child do |child| | |
renderable_node(child, options) | |
end | |
end | |
end | |
end | |
def matches_conditional_block?(block, options = {}) | |
unless block.methods.include?(:conditions) | |
return false | |
end | |
if block.conditions.blank? | |
return false | |
end | |
conditions = block.conditions.first | |
var = conditions[0] | |
matcher = conditions[1] | |
matches = conditions[2] | |
# The var needs to be in the options | |
if !options.keys.include?(var) | |
return false | |
end | |
case matcher | |
when :any? | |
# If it's any, it needs to match one of the matches | |
return matches.include?(options[var]) | |
when :all? | |
# If it's all, it needs to match all of the matches | |
return matches == [options[var]] | |
when :none? | |
# If it's none, it needs to not match the matches | |
return !matches.include?(options[var]) | |
else | |
return false | |
end | |
end | |
def renderable?(node) | |
renderable = [ | |
CSL::Style::Text, | |
CSL::Style::Names, | |
CSL::Style::Date | |
] | |
renderable.include?(node.class) | |
end | |
# LOG.puts run({type: 'book'}) | |
run({type: type}) | |
LOG.puts "\n----------------------------------------------------------------------\n\n\n" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment