quickcite 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/quickcite.rb +35 -20
- data/lib/quickcite/citeulike.rb +2 -2
- data/lib/quickcite/dblp.rb +35 -17
- data/lib/quickcite/version.rb +1 -1
- data/test/foobar.json +50 -0
- data/test/test_quickcite.rb +1 -8
- metadata +5 -5
- data/lib/quickcite/json.rb +0 -46
data/Gemfile.lock
CHANGED
data/lib/quickcite.rb
CHANGED
@@ -11,9 +11,19 @@ require "quickcite/citeulike"
|
|
11
11
|
require "quickcite/dblp"
|
12
12
|
|
13
13
|
module QuickCite
|
14
|
-
CITE_REGEX = /\\cite
|
14
|
+
CITE_REGEX = /\\cite[tp]?\{([^\}]+)\}/
|
15
15
|
SPLIT_REGEX = /([A-Z]+[a-z]+|[0-9]+|[^\\p]+)/
|
16
16
|
|
17
|
+
class Result < Struct.new(:title, :venue, :authors, :url, :date)
|
18
|
+
def initialize(hash)
|
19
|
+
super(*hash.values_at(:title, :venue, :authors, :url, :date))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.run(latex_files, bibtex_file)
|
24
|
+
Main.new(latex_files, bibtex_file)
|
25
|
+
end
|
26
|
+
|
17
27
|
# Convert a citation reference (e.g "PowerPiccolo2008") into a
|
18
28
|
# list of strings appropriate for submission to a search engine.
|
19
29
|
#
|
@@ -21,13 +31,23 @@ module QuickCite
|
|
21
31
|
def self.cite_to_query(cite)
|
22
32
|
cite.scan(SPLIT_REGEX).map { |w| w[0] }
|
23
33
|
end
|
24
|
-
|
34
|
+
|
35
|
+
# Query the user for a result from the result list to
|
36
|
+
# use for this citation reference.
|
37
|
+
#
|
38
|
+
# Returns the selected reference or nil if no match
|
39
|
+
# was selected.
|
25
40
|
def self.ask_user(cite, result_list)
|
41
|
+
if result_list.empty? then
|
42
|
+
return nil
|
43
|
+
end
|
44
|
+
|
26
45
|
puts "Result to use for \{#{cite}\}: "
|
27
46
|
puts " (0) Skip this citation"
|
28
47
|
result_list.each_with_index do |r, idx|
|
29
|
-
puts " (#{idx + 1}) #{r.title}"
|
30
|
-
puts " #{r.authors.join(', ')}"
|
48
|
+
puts " (#{idx + 1}) #{r.title} (#{r.date})"
|
49
|
+
puts " Authors: #{r.authors.join(', ')}"
|
50
|
+
puts " Venue: #{r.venue}"
|
31
51
|
end
|
32
52
|
|
33
53
|
c = HighLine::SystemExtensions::get_character.chr.to_i
|
@@ -35,7 +55,7 @@ module QuickCite
|
|
35
55
|
return result_list[c - 1]
|
36
56
|
end
|
37
57
|
end
|
38
|
-
|
58
|
+
|
39
59
|
class Main
|
40
60
|
include QuickCite
|
41
61
|
def initialize(latex_files, bibtex_file)
|
@@ -45,13 +65,13 @@ module QuickCite
|
|
45
65
|
puts "Bibtex file #{bibtex_file} does not exist. Creating an empty file."
|
46
66
|
open(bibtex_file, "w").write("")
|
47
67
|
end
|
48
|
-
|
68
|
+
|
49
69
|
@bib = BibTeX.open(bibtex_file, :include => [:meta_content])
|
50
|
-
|
51
|
-
latex_files.each
|
70
|
+
|
71
|
+
latex_files.each { |f|
|
52
72
|
puts("Processing... #{f}")
|
53
73
|
process_latex(f)
|
54
|
-
|
74
|
+
}
|
55
75
|
|
56
76
|
puts("Writing bibtex...")
|
57
77
|
outfile = open(bibtex_file, "w")
|
@@ -64,7 +84,7 @@ module QuickCite
|
|
64
84
|
e.key = cite
|
65
85
|
@bib << e
|
66
86
|
end
|
67
|
-
|
87
|
+
|
68
88
|
def process_cite(cite)
|
69
89
|
if @bib.has_key?(cite) then
|
70
90
|
puts("Skipping matched reference #{cite}")
|
@@ -81,19 +101,14 @@ module QuickCite
|
|
81
101
|
end
|
82
102
|
end
|
83
103
|
end
|
84
|
-
|
104
|
+
|
85
105
|
def process_latex(f)
|
86
106
|
latex = File.read(f)
|
87
|
-
latex.scan(CITE_REGEX)
|
88
|
-
m[0].split(",").map
|
107
|
+
latex.scan(CITE_REGEX) { |m|
|
108
|
+
m[0].split(",").map { |c|
|
89
109
|
process_cite(c)
|
90
|
-
|
91
|
-
|
92
|
-
puts(f)
|
110
|
+
}
|
111
|
+
}
|
93
112
|
end
|
94
113
|
end
|
95
|
-
|
96
|
-
def self.run(latex_files, bibtex_file)
|
97
|
-
Main.new(latex_files, bibtex_file)
|
98
|
-
end
|
99
114
|
end
|
data/lib/quickcite/citeulike.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
require "net/http"
|
8
8
|
require "uri"
|
9
|
-
require "
|
9
|
+
require "json"
|
10
10
|
|
11
11
|
module QuickCite
|
12
12
|
class CiteULike
|
@@ -19,7 +19,7 @@ module QuickCite
|
|
19
19
|
request = Net::HTTP::Get.new(SEARCH_BASE)
|
20
20
|
request.set_form_data({ "q" => query })
|
21
21
|
response = http.request(request)
|
22
|
-
js =
|
22
|
+
js = JSON.parse(response.body)
|
23
23
|
return js
|
24
24
|
end
|
25
25
|
|
data/lib/quickcite/dblp.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
require "net/http"
|
8
8
|
require "nokogiri"
|
9
|
-
require "
|
9
|
+
require "json"
|
10
10
|
require "uri"
|
11
11
|
|
12
12
|
module QuickCite
|
@@ -15,34 +15,52 @@ module QuickCite
|
|
15
15
|
# the q= argument has to come first.
|
16
16
|
SEARCH_BASE = "http://www.dblp.org/search/api/?"
|
17
17
|
SEARCH_SUFFIX = "&c=4&f=0&format=json&h=10"
|
18
|
-
|
19
|
-
|
18
|
+
|
19
|
+
def hit_to_result(h)
|
20
|
+
t = h["title"]
|
21
|
+
title = t["dblp:title"]["text"]
|
22
|
+
venue = t["dblp:venue"]["text"]
|
23
|
+
authors = t["dblp:authors"]["dblp:author"]
|
24
|
+
date = t["dblp:year"].to_s
|
25
|
+
Result.new(
|
26
|
+
:title => title,
|
27
|
+
:authors => authors.to_a,
|
28
|
+
:url => h["url"],
|
29
|
+
:venue => venue,
|
30
|
+
:date => date)
|
31
|
+
end
|
32
|
+
|
20
33
|
def search(query)
|
21
|
-
#
|
34
|
+
#json = JSON.parse(File.read("test/foobar.json"))
|
22
35
|
query_str = "q=" + URI::escape(query.join(" "))
|
23
36
|
uri = URI::parse(SEARCH_BASE + query_str + SEARCH_SUFFIX)
|
24
37
|
|
38
|
+
puts("Fetching from #{uri}")
|
39
|
+
|
25
40
|
response = Net::HTTP::get(uri)
|
26
|
-
json =
|
27
|
-
|
28
|
-
json
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
41
|
+
json = JSON.parse(response)
|
42
|
+
|
43
|
+
hits = json["result"]["hits"]["hit"]
|
44
|
+
|
45
|
+
# NB. when there is only a single result DBLP returns a single
|
46
|
+
# hit element instead of an array.
|
47
|
+
case hits
|
48
|
+
when Array
|
49
|
+
hits.map { |h| hit_to_result(h) }
|
50
|
+
else
|
51
|
+
[hit_to_result(hits)]
|
33
52
|
end
|
34
53
|
end
|
35
|
-
|
54
|
+
|
36
55
|
def bibtex(result)
|
37
56
|
# dom = Nokogiri.Slop(open("test/power-piccolo.html"))
|
38
|
-
puts("RESULT #{result.url}")
|
39
57
|
dom = Nokogiri.Slop Net::HTTP.get(URI::parse(result.url))
|
40
58
|
entries = dom.html.body.pre
|
41
59
|
case entries
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
60
|
+
when Nokogiri::XML::NodeSet
|
61
|
+
return entries[0].to_str
|
62
|
+
else
|
63
|
+
return entries.to_str
|
46
64
|
end
|
47
65
|
end
|
48
66
|
end
|
data/lib/quickcite/version.rb
CHANGED
data/test/foobar.json
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"result":{
|
3
|
+
"query":"Foo Bar",
|
4
|
+
"status":
|
5
|
+
{
|
6
|
+
"@code":12,"text":"OK"
|
7
|
+
},
|
8
|
+
"time":{
|
9
|
+
"@unit":"msecs",
|
10
|
+
"text":2.73
|
11
|
+
},
|
12
|
+
"completions":{
|
13
|
+
"@total":1,
|
14
|
+
"@computed":1,
|
15
|
+
"@sent":1,
|
16
|
+
"c":{
|
17
|
+
"@sc":2,
|
18
|
+
"@dc":1,
|
19
|
+
"@oc":1,
|
20
|
+
"@id":612166,
|
21
|
+
"text":"bar"
|
22
|
+
}
|
23
|
+
},
|
24
|
+
"hits":{
|
25
|
+
"@total":1,
|
26
|
+
"@computed":1,
|
27
|
+
"@sent":1,
|
28
|
+
"@first":0,
|
29
|
+
"hit":{
|
30
|
+
"@score":102,
|
31
|
+
"@id":2014945,
|
32
|
+
"title":{
|
33
|
+
"dblp:authors":{
|
34
|
+
"dblp:author":[
|
35
|
+
"Chee-Kit Looi",
|
36
|
+
"Foo-Keong Ng",
|
37
|
+
"Tek-Hong Kho"]},
|
38
|
+
"dblp:title":{
|
39
|
+
"@ee":"http://www.booksonline.iospress.nl/Content/View.aspx?piid=7515",
|
40
|
+
"text":"Technology-Enabled Pedagogy to Bridge Bar Diagrams to Letter-Symbolic Algebra. "},
|
41
|
+
"dblp:venue":{
|
42
|
+
"@url":"db/conf/icce/icce2007.html#LooiNK07",
|
43
|
+
"text":"ICCE 2007:29-36"},
|
44
|
+
"dblp:year":2007,
|
45
|
+
"dblp:type":"inproceedings"},
|
46
|
+
"url":"http://www.dblp.org/rec/bibtex/conf/icce/LooiNK07"
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
data/test/test_quickcite.rb
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "quickcite"
|
4
|
-
require "quickcite/json"
|
5
4
|
|
6
5
|
require "test/unit"
|
7
6
|
|
8
|
-
class TestJson < Test::Unit::TestCase
|
9
|
-
def test_simple()
|
10
|
-
v = QuickCite::JSONUtil.parse(File.read('test/power-piccolo.json'))
|
11
|
-
v.result.hits.hit.map { |h| puts(h.url) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
7
|
class TestMain < Test::Unit::TestCase
|
16
8
|
def test_simple()
|
17
9
|
texfile = open("/tmp/test.tex", "w")
|
@@ -19,6 +11,7 @@ class TestMain < Test::Unit::TestCase
|
|
19
11
|
This is a test latex file.
|
20
12
|
I like to cite \\cite{PowerPiccolo}
|
21
13
|
And \\cite{MapreduceDean}
|
14
|
+
ANd \\citet{FooBar}
|
22
15
|
END
|
23
16
|
texfile.close
|
24
17
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quickcite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 4
|
10
|
+
version: 1.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Russell Power
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-23 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bibtex-ruby
|
@@ -84,10 +84,10 @@ files:
|
|
84
84
|
- lib/quickcite.rb
|
85
85
|
- lib/quickcite/citeulike.rb
|
86
86
|
- lib/quickcite/dblp.rb
|
87
|
-
- lib/quickcite/json.rb
|
88
87
|
- lib/quickcite/version.rb
|
89
88
|
- quickcite.gemspec
|
90
89
|
- test/dean.html
|
90
|
+
- test/foobar.json
|
91
91
|
- test/power-piccolo.html
|
92
92
|
- test/power-piccolo.json
|
93
93
|
- test/test_quickcite.rb
|
data/lib/quickcite/json.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# JSON utilities.
|
2
|
-
require "json"
|
3
|
-
|
4
|
-
module QuickCite
|
5
|
-
module JSONUtil
|
6
|
-
class JSONDict
|
7
|
-
extend Forwardable
|
8
|
-
include Enumerable
|
9
|
-
attr_reader :dict
|
10
|
-
|
11
|
-
def initialize(d)
|
12
|
-
@dict = d
|
13
|
-
end
|
14
|
-
|
15
|
-
def method_missing name, *args
|
16
|
-
return JSONUtil._wrap(@dict[name.to_s])
|
17
|
-
end
|
18
|
-
|
19
|
-
def [](key)
|
20
|
-
JSONUtil._wrap(@dict[key])
|
21
|
-
end
|
22
|
-
|
23
|
-
def each
|
24
|
-
case @dict
|
25
|
-
when Hash
|
26
|
-
@dict.each_key { |k| yield self[k] }
|
27
|
-
when Array
|
28
|
-
@dict.each_index { |k| yield self[k] }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self._wrap(value)
|
34
|
-
case value
|
35
|
-
when Hash, Array
|
36
|
-
JSONDict.new(value)
|
37
|
-
else
|
38
|
-
value
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.parse(str)
|
43
|
-
d = JSONDict.new(JSON.parse(str))
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|