bento_search 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.md +131 -74
  2. data/app/assets/javascripts/bento_search/ajax_load.js +12 -4
  3. data/app/assets/stylesheets/bento_search/suggested_styles.css +4 -4
  4. data/app/helpers/bento_search_helper.rb +114 -27
  5. data/app/item_decorators/bento_search/decorator_base.rb +53 -0
  6. data/app/item_decorators/bento_search/ebscohost/conditional_openurl_main_link.rb +36 -0
  7. data/app/item_decorators/bento_search/no_links.rb +3 -2
  8. data/app/item_decorators/bento_search/only_premade_openurl.rb +4 -0
  9. data/app/item_decorators/bento_search/openurl_add_other_link.rb +4 -0
  10. data/app/item_decorators/bento_search/openurl_main_link.rb +4 -0
  11. data/app/item_decorators/bento_search/standard_decorator.rb +122 -0
  12. data/app/models/bento_search/multi_searcher.rb +13 -6
  13. data/app/models/bento_search/openurl_creator.rb +25 -5
  14. data/app/models/bento_search/result_item.rb +25 -83
  15. data/app/models/bento_search/results/pagination.rb +8 -2
  16. data/app/models/bento_search/search_engine.rb +29 -23
  17. data/app/search_engines/bento_search/ebsco_host_engine.rb +161 -25
  18. data/app/search_engines/bento_search/eds_engine.rb +1 -44
  19. data/app/search_engines/bento_search/google_books_engine.rb +61 -14
  20. data/app/search_engines/bento_search/google_site_search_engine.rb +3 -1
  21. data/app/search_engines/bento_search/mock_engine.rb +4 -0
  22. data/app/search_engines/bento_search/primo_engine.rb +2 -3
  23. data/app/search_engines/bento_search/scopus_engine.rb +1 -0
  24. data/app/search_engines/bento_search/summon_engine.rb +5 -1
  25. data/app/search_engines/bento_search/worldcat_sru_dc_engine.rb +36 -8
  26. data/app/views/bento_search/_item_title.html.erb +29 -0
  27. data/app/views/bento_search/_no_results.html.erb +3 -0
  28. data/app/views/bento_search/_search_error.html.erb +19 -15
  29. data/app/views/bento_search/_std_item.html.erb +55 -30
  30. data/app/views/bento_search/search/search.html.erb +7 -0
  31. data/config/locales/en.yml +22 -0
  32. data/lib/bento_search/util.rb +63 -1
  33. data/lib/bento_search/version.rb +1 -1
  34. data/test/decorator/decorator_base_test.rb +72 -0
  35. data/test/decorator/standard_decorator_test.rb +55 -0
  36. data/test/dummy/db/development.sqlite3 +0 -0
  37. data/test/dummy/log/development.log +12 -0
  38. data/test/dummy/log/test.log +119757 -0
  39. data/test/functional/bento_search/search_controller_test.rb +28 -0
  40. data/test/helper/bento_search_helper_test.rb +71 -0
  41. data/test/helper/bento_truncate_helper_test.rb +71 -0
  42. data/test/unit/ebsco_host_engine_test.rb +110 -3
  43. data/test/unit/google_books_engine_test.rb +22 -14
  44. data/test/unit/google_site_search_test.rb +11 -4
  45. data/test/unit/item_decorators_test.rb +6 -65
  46. data/test/unit/openurl_creator_test.rb +87 -8
  47. data/test/unit/result_item_test.rb +1 -11
  48. data/test/unit/search_engine_base_test.rb +25 -2
  49. data/test/unit/search_engine_test.rb +16 -0
  50. data/test/unit/summon_engine_test.rb +3 -0
  51. data/test/vcr_cassettes/ebscohost/another_dissertation.yml +148 -0
  52. data/test/vcr_cassettes/ebscohost/dissertation_example.yml +218 -0
  53. data/test/vcr_cassettes/ebscohost/fulltext_info.yml +1306 -0
  54. data/test/vcr_cassettes/ebscohost/live_book_example.yml +130 -0
  55. data/test/vcr_cassettes/ebscohost/live_dissertation.yml +148 -0
  56. data/test/vcr_cassettes/ebscohost/live_pathological_book_item_example.yml +215 -0
  57. data/test/vcr_cassettes/google_site/gets_format_string.yml +232 -0
  58. data/test/vcr_cassettes/max_out_pagination.yml +155 -0
  59. data/test/vcr_cassettes/worldcat_sru_dc/max_out_pagination.yml +167 -0
  60. data/test/view/std_item_test.rb +25 -8
  61. metadata +45 -12
  62. data/test/unit/result_item_display_test.rb +0 -39
  63. data/test/unit/worldcat_sru_dc_engine_test.rb +0 -120
@@ -5,6 +5,9 @@
5
5
  #
6
6
  # You don't normally create one of these yourself, you get one returned
7
7
  # from Results#pagination
8
+ #
9
+ #
10
+ # <%= paginate @results.pagination %>
8
11
  class BentoSearch::Results::Pagination
9
12
 
10
13
  # first arg is results.total_items, second is result
@@ -12,9 +15,11 @@ class BentoSearch::Results::Pagination
12
15
  #
13
16
  # We don't do the page/start normalization calc here,
14
17
  # we count on them both being passed in, already calculated
15
- # by normalize_arguments in SearchResults. Expect :page, 0-based
16
- # :start, and :per_page
18
+ # by normalize_arguments in SearchResults. Expects :page, 0-based
19
+ # :start, and 1-based :per_page to all be passed in in initializer.
17
20
  def initialize(total, normalized_args)
21
+ normalized_args ||= {} # in some error cases, we end up with nil
22
+
18
23
  @total_count = total || 0
19
24
  @per_page = normalized_args[:per_page] || 10
20
25
  @current_page = normalized_args[:page] || 1
@@ -42,6 +47,7 @@ class BentoSearch::Results::Pagination
42
47
  def count_records
43
48
  @total_count
44
49
  end
50
+ alias count count_records
45
51
 
46
52
  def total_pages
47
53
  (@total_count.to_f / @per_page).ceil
@@ -49,13 +49,11 @@ module BentoSearch
49
49
  # Additional standard configuration keys that are implemented by the bento_search
50
50
  # framework:
51
51
  #
52
- # [item_decorators]
53
- # Array of Modules (or strings specifying modules, helpful to keep
54
- # config serializable) that will be decorated on to each individual search
55
- # BentoSearch::ResultItem. These can be used to, via configuration, change
56
- # the links associated with items, change certain item behaviors, or massage
57
- # item metadata. (Needs more documentation).
58
- #
52
+ # [for_display.decorator]
53
+ # String name of decorator class that will be applied by #bento_decorate
54
+ # helper in standard view. See wiki for more info on decorators. Must be
55
+ # string name, actual class object not supported (to make it easier
56
+ # to serialize and transport configuration).
59
57
  #
60
58
  # == Implementing a SearchEngine
61
59
  #
@@ -143,8 +141,7 @@ module BentoSearch
143
141
  # merge in current instance config
144
142
  self.configuration.configure ( aConfiguration )
145
143
 
146
- # global defaults?
147
- self.configuration[:item_decorators] ||= []
144
+ # global defaults?
148
145
  self.configuration[:for_display] ||= {}
149
146
 
150
147
  # check for required keys -- have to be present, and not nil
@@ -185,6 +182,9 @@ module BentoSearch
185
182
  #
186
183
  # Ask an engine what semantic field names it supports with `engine.semantic_search_keys`
187
184
  #
185
+ # Unrecognized search fields will be ignored, unless you pass in
186
+ # :unrecognized_search_field => :raise (or do same in config).
187
+ #
188
188
  # Ask an engine what sort fields it supports with `engine.sort_keys`. See
189
189
  # list of standard sort keys in I18n file at ./config/locales/en.yml, in
190
190
  # `en.bento_search.sort_keys`.
@@ -207,8 +207,7 @@ module BentoSearch
207
207
  arguments = normalized_search_arguments(*arguments)
208
208
 
209
209
  results = search_implementation(arguments)
210
-
211
- decorate(results)
210
+
212
211
 
213
212
  # standard result metadata
214
213
  results.start = arguments[:start] || 0
@@ -220,6 +219,7 @@ module BentoSearch
220
219
  results.timing = (Time.now - start_t)
221
220
 
222
221
  results.display_configuration = configuration.for_display
222
+ results.each {|item| item.decorator = configuration.lookup!("for_display.decorator") }
223
223
 
224
224
  return results
225
225
  rescue *auto_rescue_exceptions => e
@@ -301,14 +301,17 @@ module BentoSearch
301
301
 
302
302
  # translate semantic_search_field to search_field, or raise if
303
303
  # can't.
304
- if (semantic = arguments.delete(:semantic_search_field)) && ! semantic.blank?
305
-
304
+ if (semantic = arguments.delete(:semantic_search_field)) && ! semantic.blank?
306
305
  mapped = self.semantic_search_map[semantic.to_s]
307
- unless mapped
306
+ if config_arg(arguments, :unrecognized_search_field) == "raise" && ! mapped
308
307
  raise ArgumentError.new("#{self.class.name} does not know about :semantic_search_field #{semantic}")
309
308
  end
310
309
  arguments[:search_field] = mapped
310
+ end
311
+ if config_arg(arguments, :unrecognized_search_field) == "raise" && ! search_keys.include?(arguments[:search_field])
312
+ raise ArgumentError.new("#{self.class.name} does not know about :search_field #{arguments[:search_field]}")
311
313
  end
314
+
312
315
 
313
316
  return arguments
314
317
  end
@@ -328,16 +331,19 @@ module BentoSearch
328
331
 
329
332
  protected
330
333
 
331
- # Extend each result with each specified decorator module
332
- # configuration.item_decorators is an array of either Module constants,
333
- # or strings specifying module constants.
334
- def decorate(results)
335
- results.each do |result|
336
- configuration.item_decorators.each do |decorator|
337
- decorator = (decorator.kind_of? Module) ? decorator : BentoSearch::Util.constantize(decorator)
338
- result.extend decorator
339
- end
334
+ # get value of an arg that can be supplied in search args OR config,
335
+ # with search_args over-ridding config. Also normalizes value to_s
336
+ # (for symbols/strings).
337
+ def config_arg(arguments, key, default = nil)
338
+ value = if arguments[key].present?
339
+ arguments[key]
340
+ else
341
+ configuration[key]
340
342
  end
343
+
344
+ value = value.to_s if value.kind_of? Symbol
345
+
346
+ return value
341
347
  end
342
348
 
343
349
  # What exceptions should our #search wrapper rescue and turn
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'nokogiri'
2
4
 
3
5
  require 'http_client_patch/include_client'
@@ -10,7 +12,41 @@ require 'httpclient'
10
12
  #
11
13
  # * profile_id
12
14
  # * profile_password
13
- # * databases: ARRAY of ebsco shortcodes of what databases to include in search. If you specify one you don't have access to, you get an error message from ebsco, alas.
15
+ # * databases: ARRAY of ebsco shortcodes of what databases to include in search. If you specify one you don't have access to, you get an error message from ebsco, alas.
16
+ #
17
+ #
18
+ # == Limits
19
+ #
20
+ # While waiting for a future bento_box generalized limit api, this engine
21
+ # accepts custom search arguments to apply limits:
22
+ #
23
+ # [:peer_reviewed_only] Set to boolean true or string 'true', to restrict
24
+ # results to peer-reviewed only. (Or ask EBSCOHost
25
+ # api to do so, what we get is what we get).
26
+ # [:pubyear_start]
27
+ # [:pubyear_end] Date range limiting, pass in custom search args,
28
+ # one or both of pubyear_start and pubyear_end
29
+ # #to_i will be called on it, so can be string.
30
+ # .search(:query => "foo", :pubyear_start => 2000)
31
+ #
32
+ # == Custom response data
33
+ #
34
+ # Iff EBSCO API reports that fulltext is available for the hit, then
35
+ # result.custom_data["fulltext_formats"] will be non-nil, and will be an array of
36
+ # one or more of EBSCO's internal codes (P=PDF, T=HTML, C=HTML+Images). If
37
+ # no fulltext is avail according to EBSCO API, result.custom_data["fulltext_formats"]
38
+ # will be nil.
39
+ #
40
+ # #link_is_fulltext also set to true/false
41
+ #
42
+ # You can use this to, for instance, hyperlink the displayed title directly
43
+ # to record on EBSCO if and only if there's fulltext. By writing a custom
44
+ # decorator. See wiki on decorators.
45
+ #
46
+ # == Limitations
47
+ # We do set language of ResultItems based on what ebsco tells us, but ebsoc
48
+ # seems to often leave out language or say 'english' for things that are not
49
+ # (maybe cause abstract is in English?). Config variable to tell us to ignore language?
14
50
  #
15
51
  # == Note on including databases
16
52
  #
@@ -59,12 +95,11 @@ require 'httpclient'
59
95
  # * DTD of XML Response, hard to interpret but all we've got: http://support.ebsco.com/eit/docs/DTD_EIT_WS_searchResponse.zip
60
96
  #
61
97
  # Hard to find docs page on embedding EBSCO limiters (like peer reviewed only "RV Y") in search query:
62
- # http://eit.ebscohost.com/Pages/MethodDescription.aspx?service=~/Services/SearchService.asmx&method=Info
98
+ # http://support.epnet.com/knowledge_base/detail.php?id=5397
63
99
  #
64
- # == Limitations
65
- # We do set language of ResultItems based on what ebsco tells us, but ebsoc
66
- # seems to tell us 'english' for everything (maybe cause abstract is in
67
- # English?). Config variable to tell us to ignore language?
100
+ # EBSCO searchable support portal has a section for the EIT api we use here:
101
+ # http://support.epnet.com/knowledge_base/search.php?keyword=&interface_id=1082&document_type=&page_function=search
102
+
68
103
  class BentoSearch::EbscoHostEngine
69
104
  include BentoSearch::SearchEngine
70
105
 
@@ -100,6 +135,7 @@ class BentoSearch::EbscoHostEngine
100
135
  (fault = xml.at_xpath("./Fault")))
101
136
 
102
137
  results.error ||= {}
138
+ results.error[:api_url] = url
103
139
  results.error[:exception] = exception if exception
104
140
  results.error[:status] = response.status if response
105
141
 
@@ -126,6 +162,19 @@ class BentoSearch::EbscoHostEngine
126
162
 
127
163
  end
128
164
 
165
+ # pass in nokogiri record xml for the records/rec node.
166
+ # Returns nil if NO fulltext is avail on ebsco platform,
167
+ # non-nil if fulltext is available. Non-nil value will
168
+ # actually be a non-empty ARRAY of internal EBSCO codes, P=PDF, T=HTML, C=HTML with images.
169
+ # http://support.epnet.com/knowledge_base/detail.php?topic=996&id=3778&page=1
170
+ def fulltext_formats(record_xml)
171
+ fulltext_formats = record_xml.xpath("./header/controlInfo/artinfo/formats/fmt/@type").collect {|n| n.text }
172
+
173
+ return nil if fulltext_formats.empty?
174
+
175
+ return fulltext_formats
176
+ end
177
+
129
178
 
130
179
  # Pass in a nokogiri node, return node.text, or nil if
131
180
  # arg was nil or node.text was blank?
@@ -144,13 +193,22 @@ class BentoSearch::EbscoHostEngine
144
193
  def sniff_format(xml_node)
145
194
  return nil if xml_node.nil?
146
195
 
147
-
148
- if xml_node.at_xpath("./jinfo/*") && xml_node.at_xpath("./artinfo/*")
196
+ if xml_node.at_xpath("./dissinfo/*")
197
+ :dissertation
198
+ elsif xml_node.at_xpath("./jinfo/*") && xml_node.at_xpath("./artinfo/*")
149
199
  "Article"
200
+ elsif xml_node.at_xpath("./dissinfo/disstl")
201
+ :dissertation
202
+ elsif xml_node.at_xpath("./bkinfo") && xml_node.at_xpath("./chapinfo")
203
+ :book_item
204
+ elsif xml_node.at_xpath("./bkinfo/btl") && xml_node.at_xpath("./artinfo/tig/atl") &&
205
+ (text_if_present(xml_node.at_xpath "./bkinfo/btl") != text_if_present(xml_node.at_xpath "./artinfo/tig/atl"))
206
+ # pathological case of book_item, if it has a bkinfo and an artinfo
207
+ # but the titles in both sections MATCH, it's just a book. If they're
208
+ # differnet, it's a book section, bah@
209
+ :book_item
150
210
  elsif xml_node.at_xpath("./bkinfo/*")
151
211
  "Book"
152
- elsif xml_node.at_xpath("./dissinfo/*")
153
- :dissertation
154
212
  elsif xml_node.at_xpath("./jinfo/*")
155
213
  :serial
156
214
  else
@@ -174,10 +232,15 @@ class BentoSearch::EbscoHostEngine
174
232
  components = components.collect {|a| a.titlecase if a}
175
233
  components.uniq! # no need to have the same thing twice
176
234
 
235
+
177
236
  # some hard-coded cases for better user-displayable string, and other
178
237
  # normalization.
179
238
  if ["Academic Journal", "Journal"].include?(components.first) && ["Article", "Journal Article"].include?(components.last)
180
239
  return "Journal Article"
240
+ elsif components.last == "Book: Monograph"
241
+ return "Book" # Book: Monograph what??
242
+ elsif components.first == "Book Article"
243
+ return "Book Chapter"
181
244
  elsif components.first == "Periodical" && components.length > 1
182
245
  return components.last
183
246
  elsif components.size == 2 && components.first.include?(components.last)
@@ -207,7 +270,19 @@ class BentoSearch::EbscoHostEngine
207
270
 
208
271
  # undocumented but question mark seems to cause a problem for ebsco,
209
272
  # even inside quoted phrases, not sure why.
210
- txt.gsub(/[)(\?]/, ' ')
273
+ txt = txt.gsub(/[)(\?]/, ' ')
274
+
275
+ # 'and' and 'or' need to be in phrase quotes to avoid being
276
+ # interpreted as boolean. For instance, when people just
277
+ # paste in a title: << A strategy for decreasing anxiety of ICU transfer patients and their families >>
278
+ # You'd think 'and' as boolean would still work there, but it resulted
279
+ # in zero hits unless quoted, I dunno. lowercase and uppercase and/or/not
280
+ # both cause observed weirdness.
281
+ if ['and', 'or', 'not'].include?( txt.downcase )
282
+ txt = %Q{"#{txt}"}
283
+ end
284
+
285
+ return txt
211
286
  end
212
287
 
213
288
  # Actually turn the user's query into an EBSCO "AND" boolean query,
@@ -223,14 +298,12 @@ class BentoSearch::EbscoHostEngine
223
298
  ebsco_query_escape(t)
224
299
  end
225
300
 
226
- # Remove boolean operators if they are bare not in a phrase, they'll
227
- # make things weird. In phrase quotes they are okay.
301
+
228
302
  # Remove empty strings. Remove terms that are solely punctuation
229
303
  # without any letters.
230
304
  terms.delete_if do |term|
231
305
  (
232
306
  term.blank? ||
233
- ["AND", "OR", "NOT"].include?(term) ||
234
307
  term =~ /\A[^[[:alnum:]]]+\Z/
235
308
  )
236
309
  end
@@ -251,6 +324,22 @@ class BentoSearch::EbscoHostEngine
251
324
  query = "(#{args[:search_field]} #{query})"
252
325
  end
253
326
 
327
+ # peer-reviewed only?
328
+ if [true, "true"].include? args[:peer_reviewed_only]
329
+ query += " AND (RV Y)"
330
+ end
331
+
332
+ if args[:pubyear_start] || args[:pubyear_end]
333
+ from = args[:pubyear_start].to_i
334
+ from = nil if from == 0
335
+
336
+ to = args[:pubyear_end].to_i
337
+ to = nil if to == 0
338
+
339
+ query += " AND (DT #{from}-#{to})"
340
+ end
341
+
342
+
254
343
  url += "&query=#{CGI.escape query}"
255
344
 
256
345
  # startrec is 1-based for ebsco, not 0-based like for us.
@@ -280,8 +369,33 @@ class BentoSearch::EbscoHostEngine
280
369
  item.link = get_link(xml_rec)
281
370
 
282
371
  item.issn = text_if_present info.at_xpath("./jinfo/issn")
283
-
284
- item.journal_title = text_if_present(info.at_xpath("./jinfo/jtl"))
372
+
373
+ # Dealing with titles is a bit crazy, while articles usually have atitles and
374
+ # jtitles, sometimes they have a btitle instead. A book will usually have
375
+ # both btitle and atitle, but sometimes just atitle. Book chapter, oh boy.
376
+
377
+ jtitle = text_if_present(info.at_xpath("./jinfo/jtl"))
378
+ btitle = text_if_present info.at_xpath("./bkinfo/btl")
379
+ atitle = text_if_present info.at_xpath("./artinfo/tig/atl")
380
+
381
+ if jtitle && atitle
382
+ item.title = atitle
383
+ item.source_title = jtitle
384
+ elsif btitle && atitle && atitle != btitle
385
+ # for a book, sometimes there's an atitle block and a btitle block
386
+ # when they're identical, this ain't a book section, it's a book.
387
+ item.title = atitle
388
+ item.source_title = btitle
389
+ else
390
+ item.title = atitle || btitle
391
+ end
392
+ # EBSCO sometimes has crazy long titles, truncate em.
393
+ if item.title.present?
394
+ item.title = text_helper.truncate(item.title, :length => 200, :separator => ' ', :omission => '…')
395
+ end
396
+
397
+
398
+
285
399
  item.publisher = text_if_present info.at_xpath("./pubinfo/pub")
286
400
  # if no publisher, but a dissertation institution, use that
287
401
  # as publisher.
@@ -294,11 +408,22 @@ class BentoSearch::EbscoHostEngine
294
408
  item.isbn = text_if_present info.at_xpath("./bkinfo/isbn")
295
409
 
296
410
  item.year = text_if_present info.at_xpath("./pubinfo/dt/@year")
411
+ # fill in complete publication_date too only if we've got it.
412
+ if (item.year &&
413
+ (month = text_if_present info.at_xpath("./pubinfo/dt/@month")) &&
414
+ (day = text_if_present info.at_xpath("./pubinfo/dt/@day"))
415
+ )
416
+ if (item.year.to_i != 0 && month.to_i != 0 && day.to_i != 0)
417
+ item.publication_date = Date.new(item.year.to_i, month.to_i, day.to_i)
418
+ end
419
+ end
420
+
297
421
  item.volume = text_if_present info.at_xpath("./pubinfo/vid")
298
422
  item.issue = text_if_present info.at_xpath("./pubinfo/iid")
299
423
 
300
- # EBSCO sometimes has crazy long titles, truncate em.
301
- item.title = text_helper.truncate( text_if_present( info.at_xpath("./artinfo/tig/atl") ), :length => 200)
424
+
425
+
426
+
302
427
  item.start_page = text_if_present info.at_xpath("./artinfo/ppf")
303
428
 
304
429
  item.doi = text_if_present info.at_xpath("./artinfo/ui[@type='doi']")
@@ -315,15 +440,21 @@ class BentoSearch::EbscoHostEngine
315
440
  item.authors << a
316
441
  end
317
442
 
318
-
319
- item.format = sniff_format info
320
- item.format_str = sniff_format_str info
443
+ item.format = sniff_format info
444
+ item.format_str = sniff_format_str info
321
445
 
322
446
  # Totally unreliable, seems to report english for everything? Maybe
323
- # because abstracts are in english? Nevertheless we include for now.
447
+ # because abstracts are in english? Nevertheless we include for now.
324
448
  item.language_code = text_if_present info.at_xpath("./language/@code")
325
-
326
-
449
+ # why does EBSCO return 'undetermined' sometimes? That might as well be
450
+ # not there, bah.
451
+ item.language_code = nil if item.language_code == "und"
452
+
453
+ # array of custom ebsco codes (or nil) for fulltext formats avail.
454
+ item.custom_data["fulltext_formats"] = fulltext_formats xml_rec
455
+ # if any fulltext format, mark present
456
+ item.link_is_fulltext = item.custom_data["fulltext_formats"].present?
457
+
327
458
  return item
328
459
  end
329
460
 
@@ -343,6 +474,10 @@ class BentoSearch::EbscoHostEngine
343
474
  return noko
344
475
  end
345
476
 
477
+ def public_settable_search_args
478
+ super + [:peer_reviewed_only, :pubyear_start, :pubyear_end]
479
+ end
480
+
346
481
  # David Walker says pretty much only relevance and date are realiable
347
482
  # in EBSCOhost cross-search.
348
483
  def sort_definitions
@@ -351,9 +486,10 @@ class BentoSearch::EbscoHostEngine
351
486
  "date_desc" => {:implementation => "date"}
352
487
  }
353
488
  end
354
-
489
+
355
490
  def search_field_definitions
356
491
  {
492
+ nil => {:semantic => :general},
357
493
  "AU" => {:semantic => :author},
358
494
  "TI" => {:semantic => :title},
359
495
  "SU" => {:semantic => :subject},
@@ -21,11 +21,6 @@ require 'http_client_patch/include_client'
21
21
  # If turned on, you may get <b class="bento_search_highlight"> tags
22
22
  # in title and abstract output if it's on, marked html_safe.
23
23
  #
24
- # If highlighting is on, since the abstract will be marked html safe, the
25
- # view layer won't be able to safely truncate it. In fact, it's very hard
26
- # to do here too, but we do it anyway, by default to approx configuration
27
- # truncate_highlighted num of chars (default 280). Set to nil if you don't
28
- # want this.
29
24
  #
30
25
  # == Linking
31
26
  #
@@ -394,45 +389,7 @@ class BentoSearch::EdsEngine
394
389
  else substr.html_safe
395
390
  end
396
391
  end
397
-
398
-
399
-
400
-
401
-
402
- # Crazy ass method to truncate without getting in the middle of our
403
- # html tags. This is wacky hacky, yeah.
404
- if configuration.truncate_highlighted
405
- remainingLength = configuration.truncate_highlighted
406
- in_tag = false
407
- elipses_added = false
408
-
409
- truncated_parts = []
410
- parts.each do |substr|
411
- if remainingLength <=0 && ! in_tag
412
- truncated_parts << "..."
413
- break
414
- end
415
392
 
416
- if substr =~ /^<b.*\>$/
417
- truncated_parts << substr
418
- in_tag = true
419
- elsif substr == "</b>"
420
- truncated_parts << substr
421
- in_tag = false
422
- elsif ((remainingLength - substr.length) > 0) || in_tag
423
- truncated_parts << substr
424
- else
425
- truncated_parts << helper.truncate(substr, :length => remainingLength, :separator => ' ')
426
- break
427
- end
428
-
429
- remainingLength = remainingLength - substr.length
430
- end
431
-
432
- parts = truncated_parts
433
- end
434
-
435
-
436
393
  return helper.safe_join(parts, '')
437
394
  end
438
395
 
@@ -552,7 +509,7 @@ class BentoSearch::EdsEngine
552
509
 
553
510
  def search_field_definitions
554
511
  {
555
- "TX" => {:semantic => :all},
512
+ "TX" => {:semantic => :general},
556
513
  "AU" => {:semantic => :author},
557
514
  "TI" => {:semantic => :title},
558
515
  "SU" => {:semantic => :subject},