module KramdownRFC
def self.authorps_from_hash(au)
def self.authorps_from_hash(au) aups = KramdownRFC::ParameterSet.new(au) if n = aups[:name] warn "** both name #{n} and fullname #{fn} are set on one author" if fn = aups.rest["fullname"] aups.rest["fullname"] = n usename = true end ["fullname", "ins", "initials", "surname"].each do |an| treat_multi_attribute_member(aups, an) end handle_ins(aups, :ins, "initials", "surname") handle_ins(aups, :asciiIns, "asciiInitials", "asciiSurname") # hack ("heuristic for") initials and surname from name # -- only works for people with exactly one last name and uncomplicated first names # -- add surname for people with more than one last name if usename handle_name(aups, "fullname", "initials", "surname") handle_name(aups, "asciiFullname", "asciiInitials", "asciiSurname") end aups end
def self.dateattrs(date)
def self.dateattrs(date) begin case date when /\A\d\d\d\d\z/ %{year="#{date}"} when Integer %{year="#{"%04d" % date}"} when String Date.parse("#{date}-01").strftime(%{year="%Y" month="%B"}) when Date date.strftime(%{year="%Y" month="%B" day="%d"}) when Array # this allows to explicitly give a string %{year="#{date.join(" ")}"} when nil %{year="n.d."} end rescue ArgumentError warn "*** Invalid date: #{date} -- use 2012, 2012-07, or 2012-07-28" end end
def self.escattr(str)
def self.escattr(str) escape_html(str.to_s, :attribute) end
def self.handle_ins(aups, ins_k, initials_k, surname_k)
def self.handle_ins(aups, ins_k, initials_k, surname_k) if ins = aups[ins_k] parts = ins.split('.').map(&:strip) # split on dots first if parts == [] warn "*** an empty '#{ins_k}:' value is not useful, try leaving it out" return end # Coalesce H.-P. i = 1; while i < parts.size if parts[i][0] == "-" parts[i-1..i] = [parts[i-1] + "." + parts[i]] else i += 1 end end # Multiple surnames in ins? parts[-1..-1] = parts[-1].split s = if surname = aups.rest[surname_k] surname.split else parts.reverse.take_while{|x| !looks_like_initial(x)}.reverse end aups.rest[initials_k] = initials_from_parts_and_surname(aups, parts, s) aups.rest[surname_k] = s.join(" ") end end
def self.handle_name(aups, fn_k, initials_k, surname_k)
def self.handle_name(aups, fn_k, initials_k, surname_k) if name = aups.rest[fn_k] names = name.split(/ *\| */, 2) # boundary for given/last name if names == [] warn "*** an empty '#{fn_k}:' value is not useful, try leaving it out" return end if names[1] aups.rest[fn_k] = name = names.join(" ") # remove boundary if surname = aups.rest[surname_k] if surname != names[1] warn "*** inconsistent embedded surname #{names[1]} and surname #{surname}" end end aups.rest[surname_k] = names[1] end parts = name.split if parts == [] warn "*** a blank '#{fn_k}:' value is not useful, try leaving it out" return end surname = aups.rest[surname_k] || parts[-1] s = surname.split aups.rest[initials_k] ||= initials_from_parts_and_surname(aups, parts, s) aups.rest[surname_k] = s.join(" ") end end
def self.initializify(s) # XXX Jean-Pierre
def self.initializify(s) # XXX Jean-Pierre w = '\p{Lu}\p{Lo}' if s =~ /\A[-.#{w}]+[.]/u $& elsif s =~ /\A([#{w}])[^-]*/u ret = "#$1." while (s = $') && s =~ /\A(-[\p{L}])[^-]*/u ret << "#$1." end ret else warn "*** Can't initializify #{s}" s end end
def self.initials_from_parts_and_surname(aups, parts, s)
def self.initials_from_parts_and_surname(aups, parts, s) ssz = s.size nonsurname = parts[0...-ssz] if (ns = parts[-ssz..-1]) != s warn "*** inconsistent surnames #{ns} and #{s}" end nonsurname.map{|x| initializify(x)}.join(" ") end
def self.looks_like_initial(s)
def self.looks_like_initial(s) s =~ /\A[\p{Lu}\p{Lo}]([-.][\p{Lu}\p{Lo}]?)*\z/u end
def self.person_element_from_aups(element_name, aups)
def self.person_element_from_aups(element_name, aups) erb = ERB.trim_new(PERSON_ERB, '-') erb.result(binding) end
def self.ref_to_xml(k, v)
def self.ref_to_xml(k, v) vps = KramdownRFC::ParameterSet.new(v) erb = ERB.trim_new <<-REFERB, '-' eference anchor="<%= escattr(k) %>" <%= vps.attr("target") %>> <front> <%= vps.ele("title") -%> vps.arr("author", true, true) do |au| aups = authorps_from_hash(au) %> <author <%=aups.attrs(*AUTHOR_ATTRIBUTES)%>> <%= aups.ele("organization=org", aups.attr("abbrev=orgabbrev"), "") %> </author> aups.warn_if_leftovers -%> end -%> <date <%= dateattrs(vps[:date]) %>/> </front> vps.arr("seriesinfo", false) do |k, v| -%> <seriesInfo name="<%=escattr(k)%>" value="<%=escattr(v)%>"/> end -%> vps.arr("format", false) do |k, v| -%> <format type="<%=escattr(k)%>" target="<%=escattr(v)%>"/> end -%> = vps.ele("annotation=ann", nil, nil, true) -%> = vps.ele("refcontent=rc", nil, nil, true) -%> reference> REFERB ret = erb.result(binding) vps.warn_if_leftovers ret end
def self.treat_multi_attribute_member(ps, an)
def self.treat_multi_attribute_member(ps, an) value = ps.rest[an] if Hash === value value.each do |k, v| ps.rest[if k == ':' an else Kramdown::Element.attrmangle(k + an) || Kramdown::Element.attrmangle(k) || k end] = v end end end