Created
May 3, 2013 09:42
-
-
Save inukshuk/5508232 to your computer and use it in GitHub Desktop.
Analyze CSL Styles Strip-Periods
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
require 'csl' | |
# Set the styles root directory | |
CSL::Style.root = '/Users/sylvester/Work/citeproc/styles' | |
# Set the locales root directory | |
CSL::Locale.root = '/Users/sylvester/Work/citeproc/locales' | |
# Either load all styles or those passed from command line. | |
# Calling the script with no arguments will go though all | |
# CSL files in your styles root directory | |
styles = if ARGV.empty? | |
Dir[File.join(CSL::Style.root, '**/*.csl')] | |
else | |
ARGV | |
end | |
# Define a method that analyzes a node and the translations | |
# it has produced | |
def analyze(node, translations) | |
if node[:suffix].to_s.end_with?('.') | |
# Check if all translations also end with a dot | |
if translations.all? { |t| t.end_with?('.') } | |
puts "Text node found with superfluous dot suffix!" | |
else | |
puts "Node found with dot suffix and the following translations:" | |
puts translations.join(' -- ') | |
end | |
else | |
puts "Node found with strip-periods but without dot suffix!" | |
end | |
puts | |
end | |
styles.each do |path| | |
style = CSL::Style.load path | |
# Continue only if the style has a default locale | |
if style.attribute?('default-locale') | |
puts "Checking Style #{style.id}" | |
# Load the locale | |
# --- | |
# Note that if you run this for a lot of styles | |
# this will result in the same locales being loaded | |
# over and over. | |
# To speed this up you could keep each locale around | |
# and re-use it for all styles using the same locale. | |
# --- | |
locales = [CSL::Locale.load(style['default-locale'])] | |
# Load style-local locales | |
if style.has_locale? | |
style.locale.each do |locale| | |
if locale.is_a? CSL::Locale | |
locales << locale | |
else | |
warn "Invalid locale locale detected!" | |
end | |
end | |
end | |
# Make sure that we have locales to work with | |
locales.compact! | |
if locales.empty? | |
warn "No locales were loaded!" | |
exit | |
end | |
# Define a translation helper that will use the | |
# default-locale and also each locale defined | |
# by the style itself | |
translate = lambda do |term, options| | |
translations = locales.map do |locale| | |
locale.translate term, options | |
end | |
# Skip nil values – i.e. empty translations | |
translations.compact | |
end | |
# Collect a list of all potential rendering nodes | |
nodes = [] | |
nodes << style.citation | |
nodes << style.bibliography | |
nodes.concat style.macros.values | |
# Now we map each root node to a list of its descendants | |
# to give us a list of all rendering elements in the style | |
nodes = nodes.compact.map(&:descendants).flatten(1) | |
# The above does basically the same as: | |
# rendering_nodes = [] | |
# nodes.each { |node| rendering_nodes.concat node.descendants } | |
# Find all nodes that have a 'strip-periods' attribute | |
nodes.each do |node| | |
if node.attribute?('strip-periods') | |
case node.nodename | |
when 'text' | |
if node.has_term? | |
analyze node, | |
translate.call(node[:term], node.attributes_for(:plural, :form)) | |
end | |
# Don't know if it makes sense to handle other cases of text nodes? | |
when 'label' | |
if node.name_label? | |
# Fetch the name variables | |
roles = node.parent.variable.split(/\s+/) | |
options = node.attributes_for(:form) | |
# Translate each role as singular and plural | |
translations = roles.map { |role| | |
[ | |
translate.call(role, options.merge(:plural => false)), | |
translate.call(role, options.merge(:plural => true)) | |
] | |
}.flatten | |
analyze node, translations | |
else | |
# Process regular labels | |
# TODO | |
# for node.page? translate :page singular/plural | |
# for node.locator? – translate all possible locators? | |
# for node.term? – translate the term singular/plural | |
# analyze node, translations | |
end | |
when 'date-part' | |
# TODO | |
# analyze node, translations | |
else | |
warn "Do not know how to handle #{node.nodename} nodes!" | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently this produces an output like: