summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/citation-style-language/citeproc-node-locale.lua
blob: e324c3502ebc6aafa3f4027dcc444ff0206f5f41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
local locale = {}

local element = require("citeproc-element")


local Locale = element.Element:new()

function Locale:get_option (key)
  local query = string.format("style-options[%s]", key)
  local option = self:query_selector(query)[1]
  if option then
    local value = option:get_attribute(key)
      if self.option_type[key] == "integer" then
        value = tonumber(value)
      elseif self.option_type[key] == "boolean" then
        value = (value == "true")
      end
    return value
  else
    return nil
  end
end

function Locale:get_term (name, form, number, gender)

  if form == "long" then
    form = nil
  end

  local match_last
  local match_last_two
  local match_whole
  if number then
    assert(type(number) == "number")
    match_last = string.format("%s-%02d", name, number % 10)
    match_last_two = string.format("%s-%02d", name, number % 100)
    match_whole = string.format("%s-%02s", name, number)
  end

  local res = nil
  for _, term in ipairs(self:query_selector("term")) do
    -- Use get_path?
    local match_name = name

    if number then
      local term_match = term:get_attribute("last-two-digits")
      if term_match == "whole-number" then
        match_name = match_whole
      elseif term_match == "last-two-digits" then
        match_name = match_last_two
      elseif number < 10 then
        -- "13" can match only "ordinal-13" not "ordinal-03"
        -- It is sliced to "3" in a later checking pass.
        match_name = match_last_two
      else
        match_name = match_last
      end
    end

    local term_name = term:get_attribute("name")
    local term_form = term:get_attribute("form")
    if term_form == "long" then
      term_form = nil
    end
    local term_gender = term:get_attribute("gender-form")

    if term_name == match_name and term_form == form and term_gender == gender then
      return term
    end

  end

  -- Fallback
  if form == "verb-sort" then
    return self:get_term(name, "verb")
  elseif form == "symbol" then
    return self:get_term(name, "short")
  elseif form == "verb" then
    return self:get_term(name, "long")
  elseif form == "short" then
    return self:get_term(name, "long")
  end

  if number and number > 10 then
    return self:get_term(name, nil, number % 10, gender)
  end

  if gender then
    return self:get_term(name, nil, number, nil)
  end

  if number then
    return self:get_term(name, nil, nil, nil)
  end

  return nil
end


local Term = element.Element:new()

function Term:render (context, is_plural)
  self:debug_info(context)
  context = self:process_context(context)

  local output = {
    single = self:get_text(),
  }
  for _, child in ipairs(self:get_children()) do
    if child:is_element() then
      output[child:get_element_name()] = self:escape(child:get_text())
    end
  end
  local res = output.single
  if is_plural then
    if output.multiple then
      res = output.multiple
    end
  end
  if res == "" then
    return nil
  end
  return res
end


locale.Locale = Locale
locale.Term = Term

return locale