class AnyStyle::Refs

Attributes

all[R]
max_delta[R]

Public Class Methods

new(max_delta: 10) click to toggle source
   # File lib/anystyle/refs.rb
34 def initialize(max_delta: 10)
35   @all, @max_delta = [], max_delta
36   reset
37 end
normalize!(lines, max_win_size: 2) click to toggle source
   # File lib/anystyle/refs.rb
12 def normalize!(lines, max_win_size: 2)
13   win = []
14   lines.each do |line|
15     case line.label
16     when 'text'
17       win << line
18     when 'ref'
19       unless win.length == 0 || win.length > max_win_size
20         win.each { |tk| tk.label = 'ref' }
21       end
22       win = []
23     when 'blank', 'meta'
24       # ignore
25     else
26       win = []
27     end
28   end
29 end
parse(lines, **opts) click to toggle source
   # File lib/anystyle/refs.rb
 6 def parse(lines, **opts)
 7   lines.inject(new(**opts)) do |refs, line|
 8     refs.append line.value, line.label
 9   end
10 end

Public Instance Methods

append(line, label = 'ref') click to toggle source
   # File lib/anystyle/refs.rb
57 def append(line, label = 'ref')
58   case label
59   when 'ref'
60     (line, at) = strip line
61 
62     if pending?
63       if join?(@pending, line, at - @indent)
64         @pending = join @pending, line
65       else
66         commit pending: line, indent: at
67       end
68     else
69       reset pending: line, indent: at
70     end
71   when 'meta'
72     # skip
73   when 'blank'
74     if pending?
75       if @delta > max_delta
76         commit
77       else
78         @delta += 1
79       end
80     end
81   else
82     commit if pending?
83   end
84 
85   self
86 end
commit(**opts) click to toggle source
   # File lib/anystyle/refs.rb
43 def commit(**opts)
44   @all << @pending
45   reset(**opts)
46 end
delta_score(delta = @delta) click to toggle source
    # File lib/anystyle/refs.rb
110 def delta_score(delta = @delta)
111   case delta
112   when 0 then 1
113   when 1 then 0.5
114   when 2, 3 then 0
115   else
116     delta > 6 ? -1 : -0.5
117   end
118 end
indent_depth(string) click to toggle source
    # File lib/anystyle/refs.rb
261 def indent_depth(string)
262   string[/^\s*/].length
263 end
indent_score(indent) click to toggle source
    # File lib/anystyle/refs.rb
101 def indent_score(indent)
102   case
103   when indent > 0 then 1.25
104   when indent < 0 then -1
105   else
106     0
107   end
108 end
initial_score(a, b) click to toggle source
    # File lib/anystyle/refs.rb
185 def initial_score(a, b)
186   case
187   when b.match(/^\p{Ll}/) && !b.match(/^(de|v[oa]n|v\.)\s/)
188     1.5
189   when a.match(/\p{L}$/) && b.match(/^\p{L}/)
190     1
191   when b.match(/^["'”„’‚´«「『‘“`»]/)
192     1
193   when b.match(/^(url|doi|isbn|vol)\b/i)
194     1.5
195   when b.match(/^([\p{Pd}_*][\p{Pd}_* ]+|\p{Co})/)
196     -1.5
197   when b.match(/^\((1[4-9]|2[01])\d\d\)/) && !a.match(/(\p{Lu}|al|others)\.$/)
198     -1
199   when b.match(/^\p{Lu}[\p{Ll}-]+,?\s\p{Lu}/) && !a.match(/\p{L}$/)
200     -0.5
201   when match_list?(b)
202     if match_list?(a)
203       -1.5
204     else
205       -0.75
206     end
207   when b.match(/^\p{L}+:/), b.match(/^\p{L}+ \d/)
208     0.5
209   else
210     0
211   end
212 end
join(a, b) click to toggle source
    # File lib/anystyle/refs.rb
244 def join(a, b)
245   if a =~ /\p{Pd}$/
246     if a =~ /\p{Ll}-$/ && b =~ /^\p{Ll}/
247       "#{a[0...-1]}#{b}"
248     else
249       "#{a}#{b}"
250     end
251   else
252     "#{a} #{b}"
253   end
254 end
join?(a, b, indent = 0, delta = @delta) click to toggle source
   # File lib/anystyle/refs.rb
88 def join?(a, b, indent = 0, delta = @delta)
89   score = [
90     indent_score(indent),
91     delta_score(delta),
92     years_score(a, b),
93     terminal_score(a, b),
94     initial_score(a, b),
95     length_score(a, b),
96     pages_score(a, b)
97   ]
98   score.reduce(&:+) >= 1
99 end
length_score(a, b) click to toggle source
    # File lib/anystyle/refs.rb
218 def length_score(a, b)
219   case
220   when b.length < a.length
221     case
222     when b.length < 10
223       2.5
224     when b.length < 15
225       2
226     when b.length < 20
227       1.75
228     when b.length < 25
229       1.5
230     when b.length < 30
231       1
232     when b.length < 50
233       0.75
234     else
235       0
236     end
237   when (b.length - a.length) > 12
238     -0.5
239   else
240     0
241   end
242 end
match_list?(string) click to toggle source
    # File lib/anystyle/refs.rb
214 def match_list?(string)
215   string.match(/^(\d{1,3}(\.\s+|\s{2,})\p{L}|\[\p{Alnum}+\])/)
216 end
match_pages?(string, not_years = true) click to toggle source
    # File lib/anystyle/refs.rb
161 def match_pages?(string, not_years = true)
162   m = string.match(/(\d+)\p{Pd}(\d+)|\bpp?\.|\d+\(\d+\)/)
163   return false if m.nil?
164   return false if not_years && m[1] && match_year?(m[1]) && match_year?(m[2])
165   return true
166 end
match_year?(string) click to toggle source
    # File lib/anystyle/refs.rb
145 def match_year?(string)
146   !!string.match(/\b(1[4-9]|2[01])\d\d[a-z]?\b/)
147 end
pages_score(a, b) click to toggle source
    # File lib/anystyle/refs.rb
149 def pages_score(a, b)
150   if match_pages?(a, true)
151     -0.25
152   else
153     if match_pages?(b, false)
154       1
155     else
156       0
157     end
158   end
159 end
pending?() click to toggle source
   # File lib/anystyle/refs.rb
53 def pending?
54   !@pending.nil?
55 end
reset(delta: 0, indent: 0, pending: nil) click to toggle source
   # File lib/anystyle/refs.rb
39 def reset(delta: 0, indent: 0, pending: nil)
40   @delta, @indent, @pending = delta, indent, pending
41 end
strip(string) click to toggle source
    # File lib/anystyle/refs.rb
256 def strip(string)
257   string = display_chars(string)
258   [string.lstrip, indent_depth(string)]
259 end
terminal_score(a, b) click to toggle source
    # File lib/anystyle/refs.rb
168 def terminal_score(a, b)
169   case
170   when a.match(/https?:\/\/\w+/i)
171     -0.25
172   when a.match(/[,;:&\p{Pd}]$/), a.match(/\s(et al|pp|pg)\.$/)
173     2
174   when a.match(/\((1[4-9]|2[01])\d\d\)\.?$/)
175     0
176   when a.match(/(\p{^Lu}\.|\])$/)
177     -1
178   when a.match(/\d$/) && b.match(/^\p{Lu}/)
179     -0.25
180   else
181     0
182   end
183 end
to_a() click to toggle source
   # File lib/anystyle/refs.rb
48 def to_a
49   commit if pending?
50   @all
51 end
years_score(a, b) click to toggle source
    # File lib/anystyle/refs.rb
120 def years_score(a, b)
121   if match_year?(a)
122     if match_year?(b)
123       case
124       when b.length < 18
125         1
126       when b.length < 25
127         0.5
128       when b.length > 60
129         -0.75
130       else
131         0
132       end
133     else
134       if a.match(/[\d,] \(?(1[4-9]|2[01])\d\d[a-z]?\)?\.$/)
135         -0.5
136       else
137         1
138       end
139     end
140   else
141     1
142   end
143 end