hard_citer 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/README.md +23 -2
- data/Rakefile +2 -1
- data/lib/hard_citer.rb +4 -7
- data/lib/hardciter/bibliography.rb +26 -61
- data/lib/hardciter/citation.rb +13 -0
- data/lib/hardciter/citer.rb +66 -59
- data/lib/hardciter/configuration.rb +13 -6
- data/lib/hardciter/html_output.rb +137 -0
- data/lib/hardciter/intext_match.rb +19 -0
- data/lib/hardciter/library.rb +3 -21
- data/lib/hardciter/parser.rb +46 -0
- metadata +11 -10
- data/lib/hardciter/cite_match.rb +0 -14
- data/lib/hardciter/styler.rb +0 -81
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjdkYWJkMTc2YzNhYjQxZjFkM2UxMTNkNmU3ZDAwNmE2MDBlYWFlYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTM4NjgzNWM5MWI3NjI1NmNjNzg2YjZkN2FjNzYwYmIzNjdlZTBjNQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmMzMTYzOGJkZDllMDdjMTNjYTUyMzQ3NjA5M2U0OTNlMDAwNjIzZjEwNTUz
|
10
|
+
NzY3YmMwYTAwY2JjM2Y4YzA5NTViZGQ5NmVkZjNhNmZiMDllMzljNjVmMDY5
|
11
|
+
OTIxZWQ3OWU3YjFjZTgzNTE5MzM2NDE3ZjJhYjc5NDg4MDU0ZTQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YjM5ZTQwNTNhYWUyZTI1MDExZTY5ZWFjN2M2NDE5ZWI5OTNlZGM2MDExYzMw
|
14
|
+
YjFmOTIwNjZmZmQ5ZDFhYTQwMWRjZWE3NzgzNDg4YmFkODg4Zjg1YThhYzIx
|
15
|
+
ZTRjMDZhOWJhZThiNmQ1NTY5MDVhNjJkODg2MmI3MThiNGJmMzY=
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# Hard Citer
|
1
|
+
# Hard Citer[](http://badge.fury.io/rb/hard_citer)[](https://coveralls.io/r/mcordell/hard_citer?branch=master)
|
2
|
+
|
2
3
|
Hard Citer is a solution for outputting HTML bibliographies. When used in conjuction with a "cite while you write" tool, it can make writing and editing well-cited html eaiser. Using a in-text cited HTML document and a bibtex library, it can output a properly formatted bibliography. The default configuration is geared towards usage with Papers' [magic citations][1]. Papers does not provide an easy way to perform magic citations and produce a nicely formatted bibliography for HTML, from an HTML document source.
|
3
4
|
|
4
5
|
For the best bang for your buck, use one of the text editors listed [here][2]
|
@@ -12,7 +13,13 @@ use Hard Citer.
|
|
12
13
|
|
13
14
|
##Usage
|
14
15
|
|
15
|
-
|
16
|
+
Install the hard_citer gem and require it.
|
17
|
+
|
18
|
+
```Ruby
|
19
|
+
require 'hard_citer'
|
20
|
+
```
|
21
|
+
|
22
|
+
Initialize a new Citer object by pointing it at the bib file you exported from Papers:
|
16
23
|
|
17
24
|
```Ruby
|
18
25
|
require File.expand_path("../lib/hard_citer", __FILE__)
|
@@ -39,3 +46,17 @@ citer.csl = File.expand_path("../examples/plos.csl")
|
|
39
46
|
```
|
40
47
|
|
41
48
|
|
49
|
+
##TODO
|
50
|
+
Here is a general list of how I would like to improve this gem
|
51
|
+
|
52
|
+
1. Command line commands in conjunction with a yml configuration file
|
53
|
+
2. Better support for alternate CWYW tools
|
54
|
+
3. More Tests
|
55
|
+
4. Expand the Library function so that you can use ActiveRecords or kin for easier rails support
|
56
|
+
|
57
|
+
|
58
|
+
##Contact
|
59
|
+
|
60
|
+
I would love to hear from anyone who would like me to improve this gem or who has comments and suggestions.
|
61
|
+
|
62
|
+
\[[Twitter](https://twitter.com/mike_cordell)\] | \[[Email](mailto:mike@mikecordell.com)\] | \[[Website](http://www.mikecordell.com)\]
|
data/Rakefile
CHANGED
data/lib/hard_citer.rb
CHANGED
@@ -2,15 +2,12 @@
|
|
2
2
|
require 'bibtex'
|
3
3
|
require 'citeproc'
|
4
4
|
require File.expand_path("../hardciter/bibliography.rb", __FILE__)
|
5
|
-
require File.expand_path("../hardciter/
|
5
|
+
require File.expand_path("../hardciter/citation.rb", __FILE__)
|
6
6
|
require File.expand_path("../hardciter/citer.rb", __FILE__)
|
7
7
|
require File.expand_path("../hardciter/configuration.rb", __FILE__)
|
8
8
|
require File.expand_path("../hardciter/document.rb", __FILE__)
|
9
9
|
require File.expand_path("../hardciter/exceptions.rb", __FILE__)
|
10
10
|
require File.expand_path("../hardciter/library.rb", __FILE__)
|
11
|
-
require File.expand_path("../hardciter/
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
require File.expand_path("../hardciter/html_output.rb", __FILE__)
|
12
|
+
require File.expand_path("../hardciter/parser.rb", __FILE__)
|
13
|
+
require File.expand_path("../hardciter/intext_match.rb", __FILE__)
|
@@ -1,85 +1,50 @@
|
|
1
1
|
module HardCiter
|
2
2
|
class Bibliography
|
3
|
-
attr_accessor :bibliography_intext, :intext_regex, :
|
3
|
+
attr_accessor :bibliography_intext, :intext_regex, :bib_out_line, :bib_out_match,
|
4
|
+
:citation_locations, :citations, :bit_out_location
|
4
5
|
|
5
6
|
def initialize
|
6
|
-
@bibliography_intext = HardCiter
|
7
|
-
@intext_regex = HardCiter
|
7
|
+
@bibliography_intext = HardCiter.configuration.bibliography_pattern
|
8
|
+
@intext_regex = HardCiter.configuration.intext_pattern
|
8
9
|
@citation_locations = {}
|
9
10
|
@citations = {}
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
[match.to_s, pos]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def has_bibliography_key?(line)
|
21
|
-
line =~ @bibliography_intext
|
22
|
-
end
|
23
|
-
|
24
|
-
def mark_match_positions(citation_matches,line,index)
|
25
|
-
if citation_matches.length > 1
|
26
|
-
@citation_locations[index] = group_matches(citation_matches, line)
|
13
|
+
def pair_match_to_citation(intext_match,line_num)
|
14
|
+
if intext_match.type == HardCiter::BIBLIOGRAPHY_OUT_MATCH
|
15
|
+
set_bib_out(intext_match,line_num)
|
16
|
+
nil
|
27
17
|
else
|
28
|
-
|
18
|
+
get_or_create_citation(intext_match)
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
32
|
-
def
|
33
|
-
@
|
34
|
-
|
22
|
+
def set_bib_out(intext_match,line_num)
|
23
|
+
@bib_out_line = line_num
|
24
|
+
@bib_out_match = intext_match
|
35
25
|
end
|
36
26
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if matches_are_paired?(current_match,next_match,line)
|
43
|
-
current_match = pair_two_matches(current_match, next_match)
|
44
|
-
else
|
45
|
-
matches_grouped.push(current_match) if current_match
|
46
|
-
current_match = next_match
|
47
|
-
end
|
27
|
+
def get_or_create_citation(intext_match)
|
28
|
+
if @citations.has_key?(intext_match.cite_key)
|
29
|
+
@citations[intext_match.cite_key]
|
30
|
+
else
|
31
|
+
add_citation(intext_match)
|
48
32
|
end
|
49
|
-
matches_grouped.push(current_match) unless current_match.empty?
|
50
|
-
return matches_grouped
|
51
33
|
end
|
52
34
|
|
53
|
-
def
|
54
|
-
|
55
|
-
paired_matches = current_match + next_match
|
56
|
-
else
|
57
|
-
paired_matches = [current_match,next_match]
|
58
|
-
end
|
35
|
+
def has_bibliography_key?(line)
|
36
|
+
line =~ @bibliography_intext
|
59
37
|
end
|
60
38
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if line[end_of_match] =~ /\s/
|
67
|
-
end_of_match += 1
|
68
|
-
else
|
69
|
-
false
|
70
|
-
end
|
71
|
-
end
|
72
|
-
true
|
39
|
+
def add_citation(intext_match)
|
40
|
+
citation = HardCiter::Citation.new(intext_match.cite_key)
|
41
|
+
citation.bib_number = next_citation_index
|
42
|
+
@citations[citation.key] = citation
|
43
|
+
citation
|
73
44
|
end
|
74
45
|
|
75
|
-
def
|
76
|
-
|
77
|
-
#match_group has sub arrays so it needs to be unpacked
|
78
|
-
last_match = match_group[match_group.size-1]
|
79
|
-
else
|
80
|
-
last_match = match_group
|
81
|
-
end
|
82
|
-
[last_match[0],last_match[1]]
|
46
|
+
def next_citation_index
|
47
|
+
@citations.length + 1
|
83
48
|
end
|
84
49
|
end
|
85
50
|
end
|
data/lib/hardciter/citer.rb
CHANGED
@@ -1,94 +1,101 @@
|
|
1
1
|
module HardCiter
|
2
2
|
class Citer
|
3
|
-
BIBTEX_LIBRARY_REGEX = /\.bib$/
|
4
|
-
attr_accessor :library, :styler, :csl, :bibliography
|
5
3
|
|
6
|
-
|
4
|
+
attr_accessor :library, :output, :csl, :bibliography
|
5
|
+
|
7
6
|
def initialize(path = nil)
|
8
7
|
initialize_library_by_path(path) if path
|
9
8
|
@bibliography = HardCiter::Bibliography.new
|
10
|
-
@styler = HardCiter::Styler.new
|
11
9
|
@csl = HardCiter::Configuration::CSL
|
10
|
+
@output = HardCiter::HtmlOutput.new(@csl)
|
11
|
+
@parser = HardCiter::Parser.new
|
12
12
|
end
|
13
13
|
|
14
|
-
#Citer
|
15
14
|
def initialize_library_by_path(path)
|
16
|
-
if path =~
|
15
|
+
if path =~ HardCiter.configuration.bibtex_library_regex
|
17
16
|
@library = BibTexLibrary.new(path)
|
18
17
|
else
|
19
|
-
raise "Unknown path type"
|
18
|
+
raise "Unknown library path type"
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
#Citer
|
24
22
|
def cite_text(text)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
validate_prerequisites
|
24
|
+
document = Document.new(text)
|
25
|
+
intext_matches = parse_all_lines(document)
|
26
|
+
add_and_group_intext_matches(document, intext_matches)
|
27
|
+
get_entries_from_library
|
28
|
+
@output.prepare_bibliography(@bibliography)
|
29
|
+
@output.process_and_output_text(document,intext_matches)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
32
|
+
def get_entries_from_library
|
33
|
+
raise "Library is not set. Cannot get entries." if @library.nil?
|
34
|
+
raise "Bibliography is not set. Cannot get entries." if @bibliography.nil?
|
35
|
+
raise "Bibliography has no citations" if @bibliography.citations.nil? || @bibliography.citations.empty?
|
36
|
+
@bibliography.citations.each do |cite_key,citation|
|
37
|
+
citation.entry = @library.get_entry(citation.key)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
def add_and_group_intext_matches(document,intext_matches)
|
42
|
+
intext_matches.each_with_index do |matches, index|
|
43
|
+
line = document.text_array[index]
|
44
|
+
matches.each do |match|
|
45
|
+
citation = @bibliography.pair_match_to_citation(match,index)
|
46
|
+
match.citation = citation if citation
|
47
|
+
end
|
48
|
+
group_matches!(matches,line)
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
48
|
-
|
52
|
+
def validate_prerequisites
|
53
|
+
if @library.nil?
|
54
|
+
raise "Library missing cannot proceed with citation"
|
55
|
+
elsif @csl.nil?
|
56
|
+
raise "No citation format found, cannot proceed with citation"
|
57
|
+
end
|
49
58
|
end
|
50
59
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@bibliography.citation_locations.each do |line_number,cite_matches|
|
55
|
-
text_line = output_text[line_number]
|
56
|
-
output_text[line_number] = @styler.style_line(text_line,cite_matches)
|
60
|
+
def parse_all_lines(document)
|
61
|
+
document.text_array.each_with_object([]) do |line,out|
|
62
|
+
out.push(@parser.parse_line(line))
|
57
63
|
end
|
58
|
-
output_text
|
59
64
|
end
|
60
65
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
def group_matches!(matches, line)
|
67
|
+
temp_matches = []
|
68
|
+
current_match = matches.shift unless matches.empty?
|
69
|
+
head = current_match
|
70
|
+
until matches.empty?
|
71
|
+
next_match = matches.shift
|
72
|
+
if matches_are_paired?(current_match, next_match, line)
|
73
|
+
pair_matches(current_match,next_match)
|
74
|
+
else
|
75
|
+
temp_matches.push(head)
|
76
|
+
head = next_match
|
77
|
+
end
|
78
|
+
current_match = next_match
|
73
79
|
end
|
80
|
+
temp_matches.each { |m| matches.push m }
|
81
|
+
matches.push(head)
|
74
82
|
end
|
75
83
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
private
|
85
|
+
def matches_are_paired?(match_first, match_second, line)
|
86
|
+
end_of_match = match_first.position + match_first.regex_match.length
|
87
|
+
while end_of_match < match_second.position
|
88
|
+
if line[end_of_match] =~ /\s/
|
89
|
+
end_of_match += 1
|
90
|
+
else
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
return true
|
86
95
|
end
|
87
|
-
[cite_match, match_pos]
|
88
|
-
end
|
89
96
|
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
def pair_matches(first_match, second_match)
|
98
|
+
first_match.next_in_group = second_match
|
99
|
+
end
|
93
100
|
end
|
94
101
|
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
module HardCiter
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :csl, :
|
3
|
+
attr_accessor :csl, :bibliography_pattern, :intext_pattern,
|
4
|
+
:bibtex_library_regex, :cite_key_pattern
|
4
5
|
|
5
6
|
CSL = File.expand_path("../../../examples/plos.csl", __FILE__)
|
6
7
|
|
7
|
-
|
8
|
+
BIBLIOGRAPHY_PATTERN = /\{papers2_bibliography\}/
|
9
|
+
|
10
|
+
INTEXT_PATTERN = /\{(\w*:\w*)\}/
|
11
|
+
|
12
|
+
CITE_KEY_PATTERN = /\w*:\w*/
|
13
|
+
|
14
|
+
BIBTEX_LIBRARY_REGEX = /\.bib$/
|
8
15
|
|
9
|
-
INTEXT_REGEX = /\{(\w*:\w*)\}/
|
10
16
|
|
11
17
|
def initialize
|
12
18
|
self.reset
|
@@ -14,10 +20,11 @@ module HardCiter
|
|
14
20
|
|
15
21
|
def reset
|
16
22
|
@csl = CSL
|
17
|
-
@
|
18
|
-
@
|
23
|
+
@bibliography_pattern = BIBLIOGRAPHY_PATTERN
|
24
|
+
@intext_pattern = INTEXT_PATTERN
|
25
|
+
@cite_key_pattern = CITE_KEY_PATTERN
|
26
|
+
@bibtex_library_regex = BIBTEX_LIBRARY_REGEX
|
19
27
|
end
|
20
|
-
|
21
28
|
end
|
22
29
|
|
23
30
|
class << self
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'citeproc'
|
3
|
+
module HardCiter
|
4
|
+
class HtmlOutput
|
5
|
+
attr_accessor :csl, :bibliography
|
6
|
+
|
7
|
+
def initialize(csl=nil)
|
8
|
+
@csl = csl if csl
|
9
|
+
@open_tag = '<sup>['
|
10
|
+
@close_tag = ']</sup>'
|
11
|
+
@multi_separator = ','
|
12
|
+
@separator_after_last = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_line(line,intext_matches)
|
16
|
+
intext_matches.each do |match|
|
17
|
+
line_front = line[0..match.position-1]
|
18
|
+
line_end = line[match.position+match.regex_match.length..-1]
|
19
|
+
intext_out = @open_tag + match.citation.intext_output + @close_tag
|
20
|
+
line = line_front + intext_out + line_end
|
21
|
+
end
|
22
|
+
line
|
23
|
+
end
|
24
|
+
|
25
|
+
def process_and_output_text(text,intext_matches)
|
26
|
+
text = text.text_array
|
27
|
+
raise "prepare_bibliography has not been run, cannot process text" if @bibliography.nil?
|
28
|
+
check_text_and_matches_length(text,intext_matches)
|
29
|
+
output = []
|
30
|
+
text.each_with_index do |line,index|
|
31
|
+
output+=style_line(line,intext_matches[index])
|
32
|
+
end
|
33
|
+
output
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_text_and_matches_length(text,intext_matches)
|
37
|
+
if text.length != intext_matches.length
|
38
|
+
raise "Document length and intext_matches length are different, aborting."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare_bibliography(bibliography)
|
43
|
+
@bibliography = ['<ol class="bibliography">']
|
44
|
+
bibliography.citations.each do |citation_key,citation|
|
45
|
+
entry = citation.entry
|
46
|
+
if entry.nil?
|
47
|
+
cite_text = citation_key
|
48
|
+
else
|
49
|
+
cite_text = CiteProc.process(entry.to_citeproc, style: @csl, format: :html)
|
50
|
+
strip_extra_brackets(cite_text)
|
51
|
+
@bibliography.push '<li><a name = "' +
|
52
|
+
"bibliography_#{citation.bib_number}\">" +
|
53
|
+
cite_text + '</a></li>'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
@bibliography.push('</ol>')
|
57
|
+
end
|
58
|
+
|
59
|
+
def strip_extra_brackets(line)
|
60
|
+
line.gsub!(/\{|\}/, '')
|
61
|
+
end
|
62
|
+
|
63
|
+
def style_line(line, line_matches)
|
64
|
+
pos_offset = 0
|
65
|
+
line_matches.each do |match|
|
66
|
+
if match
|
67
|
+
if match.type == BIBLIOGRAPHY_OUT_MATCH
|
68
|
+
return @bibliography
|
69
|
+
elsif match.next_in_group.nil?
|
70
|
+
line,pos_offset = single_cite(match,line,pos_offset)
|
71
|
+
else
|
72
|
+
line,pos_offset = multi_cite(match, line, pos_offset)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return [line]
|
77
|
+
end
|
78
|
+
|
79
|
+
def multi_cite(match, line, pos_offset)
|
80
|
+
original_line_length = line.length
|
81
|
+
pos = match.position + pos_offset
|
82
|
+
before,after = split_at_match(pos,match.regex_match.length,line)
|
83
|
+
after = split_group_matches(match.next_in_group,after)
|
84
|
+
intexts = []
|
85
|
+
while match do
|
86
|
+
intexts.push(get_intext(match.citation))
|
87
|
+
match = match.next_in_group
|
88
|
+
end
|
89
|
+
output_line = before + wrap_intext(intexts) + after
|
90
|
+
pos_offset += (output_line.length - original_line_length)
|
91
|
+
return output_line, pos_offset
|
92
|
+
end
|
93
|
+
|
94
|
+
def split_group_matches(match,line)
|
95
|
+
while match do
|
96
|
+
match_pos = Regexp.new(match.regex_match).match(line)
|
97
|
+
if match_pos.nil?
|
98
|
+
raise "match missing?"
|
99
|
+
else
|
100
|
+
line.slice!(match_pos.begin(0)..match.regex_match.length)
|
101
|
+
end
|
102
|
+
match = match.next_in_group
|
103
|
+
end
|
104
|
+
line
|
105
|
+
end
|
106
|
+
|
107
|
+
def split_at_match(pos,match_length,line)
|
108
|
+
pos == 0 ? before = '' : before = line.slice!(0..pos - 1)
|
109
|
+
after = line.slice(match_length,line.length)
|
110
|
+
return before,after
|
111
|
+
end
|
112
|
+
|
113
|
+
def single_cite(match, line, pos_offset)
|
114
|
+
original_line_length = line.length
|
115
|
+
pos = match.position += pos_offset
|
116
|
+
before,after = split_at_match(pos,match.regex_match.length, line)
|
117
|
+
in_text_citation = wrap_intext([get_intext(match.citation)])
|
118
|
+
output_line = before + in_text_citation + after
|
119
|
+
pos_offset += (output_line.length - original_line_length)
|
120
|
+
return output_line, pos_offset
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_intext(citation)
|
124
|
+
number = citation.bib_number
|
125
|
+
"<a href = \"#bibliography_#{number}\">#{number}</a>"
|
126
|
+
end
|
127
|
+
|
128
|
+
def wrap_intext(intext_citations)
|
129
|
+
output = @open_tag
|
130
|
+
intext_citations.each_with_index do |intext, index|
|
131
|
+
output += intext
|
132
|
+
output += @multi_separator unless index == intext_citations.length-1
|
133
|
+
end
|
134
|
+
output += @close_tag
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module HardCiter
|
3
|
+
BIBLIOGRAPHY_OUT_MATCH = 2
|
4
|
+
INTEXT_CITATION_MATCH = 1
|
5
|
+
class IntextMatch
|
6
|
+
attr_accessor :position, :type, :regex_match, :citation, :next_in_group
|
7
|
+
|
8
|
+
def initialize(position=nil, regex_match=nil, type=nil)
|
9
|
+
@position = position
|
10
|
+
@regex_match = regex_match
|
11
|
+
@type = type
|
12
|
+
end
|
13
|
+
|
14
|
+
def cite_key
|
15
|
+
match_data = HardCiter.configuration.cite_key_pattern.match(@regex_match)
|
16
|
+
match_data[0] if match_data.is_a? MatchData
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/hardciter/library.rb
CHANGED
@@ -1,36 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'bibtex'
|
3
3
|
module HardCiter
|
4
|
-
class Library < Hash
|
5
|
-
|
6
|
-
def initialize(path = nil)
|
7
|
-
load_lib(path)
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
def load_lib(path = nil)
|
12
|
-
if File.exists? path
|
13
|
-
load_from_file(path)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_citation()
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
4
|
class BibTexLibrary
|
23
5
|
attr_accessor :bibtex
|
24
6
|
|
25
|
-
def initialize(path)
|
26
|
-
load_from_file(path)
|
7
|
+
def initialize(path=nil)
|
8
|
+
load_from_file(path) if path
|
27
9
|
end
|
28
10
|
|
29
11
|
def load_from_file(path)
|
30
12
|
@bibtex = BibTeX.open(path)
|
31
13
|
end
|
32
14
|
|
33
|
-
def
|
15
|
+
def get_entry(key)
|
34
16
|
@bibtex[key]
|
35
17
|
end
|
36
18
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module HardCiter
|
3
|
+
class Parser
|
4
|
+
attr_accessor :bib_key_pattern, :citation_key_pattern
|
5
|
+
|
6
|
+
def initialize(bib_key_pattern=nil,citation_key_pattern=nil)
|
7
|
+
@bib_key_pattern = bib_key_pattern ? bib_key_pattern : HardCiter.configuration.bibliography_pattern
|
8
|
+
@citation_key_pattern = citation_key_pattern ? citation_key_pattern : HardCiter.configuration.intext_pattern
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_bibliography_key?(line)
|
12
|
+
line =~ @bib_key_pattern
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_bib_match(line)
|
16
|
+
match_data = @bib_key_pattern.match(line)
|
17
|
+
create_match(match_data, HardCiter::BIBLIOGRAPHY_OUT_MATCH)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_citation_match(match_data)
|
21
|
+
create_match(match_data, HardCiter::INTEXT_CITATION_MATCH)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_match(match_data,type)
|
25
|
+
match = HardCiter::IntextMatch.new()
|
26
|
+
match.position = match_data.begin(0)
|
27
|
+
match.type = type
|
28
|
+
match.regex_match = match_data.to_s
|
29
|
+
match
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_intext_citations(line)
|
33
|
+
line.enum_for(:scan, @citation_key_pattern).map do
|
34
|
+
create_citation_match(Regexp.last_match)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_line(line)
|
39
|
+
if has_bibliography_key?(line)
|
40
|
+
[create_bib_match(line)]
|
41
|
+
else
|
42
|
+
find_intext_citations(line)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hard_citer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Michael Cordell
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-10-12 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: ! "\nHard Citer is a solution for outputting HTML bibliographies. When
|
15
14
|
used\nin conjuction with a \"cite while you write\" tool, it can make writing and\nediting
|
@@ -27,37 +26,39 @@ files:
|
|
27
26
|
- LICENSE.txt
|
28
27
|
- lib/hard_citer.rb
|
29
28
|
- lib/hardciter/bibliography.rb
|
30
|
-
- lib/hardciter/
|
29
|
+
- lib/hardciter/citation.rb
|
31
30
|
- lib/hardciter/citer.rb
|
32
31
|
- lib/hardciter/configuration.rb
|
33
32
|
- lib/hardciter/document.rb
|
34
33
|
- lib/hardciter/exceptions.rb
|
34
|
+
- lib/hardciter/html_output.rb
|
35
|
+
- lib/hardciter/intext_match.rb
|
35
36
|
- lib/hardciter/library.rb
|
36
|
-
- lib/hardciter/
|
37
|
+
- lib/hardciter/parser.rb
|
37
38
|
- lib/scrap_methods
|
38
39
|
homepage: https://github.com/mcordell/hard_citer
|
39
|
-
licenses:
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
40
43
|
post_install_message:
|
41
44
|
rdoc_options: []
|
42
45
|
require_paths:
|
43
46
|
- lib
|
44
47
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
-
none: false
|
46
48
|
requirements:
|
47
49
|
- - ! '>='
|
48
50
|
- !ruby/object:Gem::Version
|
49
51
|
version: '0'
|
50
52
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
53
|
requirements:
|
53
54
|
- - ! '>='
|
54
55
|
- !ruby/object:Gem::Version
|
55
56
|
version: '0'
|
56
57
|
requirements: []
|
57
58
|
rubyforge_project:
|
58
|
-
rubygems_version:
|
59
|
+
rubygems_version: 2.0.7
|
59
60
|
signing_key:
|
60
|
-
specification_version:
|
61
|
+
specification_version: 4
|
61
62
|
summary: A gem to help with in-text citations in HTML documents.
|
62
63
|
test_files: []
|
63
64
|
has_rdoc:
|
data/lib/hardciter/cite_match.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module HardCiter
|
3
|
-
class CiteMatch
|
4
|
-
attr_accessor :bib_number, :citation, :in_cite_text, :key
|
5
|
-
|
6
|
-
def initialize(key, citation = nil, in_cite_text = nil)
|
7
|
-
@key = key
|
8
|
-
@citation = citation
|
9
|
-
@in_cite_text = in_cite_text
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
data/lib/hardciter/styler.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'citeproc'
|
3
|
-
module HardCiter
|
4
|
-
class Styler
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@open_tag = ''
|
8
|
-
@close_tag = ''
|
9
|
-
@multi_separator = '<sup>, </sup>'
|
10
|
-
@separator_after_last = false
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_bibliography_lines(bibliography_array, csl_style)
|
14
|
-
out_lines = ['<ol class="bibliography">']
|
15
|
-
bibliography_array.citations.each do |cite_key, cite_match|
|
16
|
-
entry = cite_match.citation
|
17
|
-
if entry.nil?
|
18
|
-
cite_text = cite_key
|
19
|
-
else
|
20
|
-
cite_text = CiteProc.process(cite_match.citation.to_citeproc,
|
21
|
-
style: csl_style, format: :html)
|
22
|
-
strip_extra_papers_brackets cite_text
|
23
|
-
end
|
24
|
-
|
25
|
-
out_lines.push '<li><a name = "' +
|
26
|
-
"bibliography_#{cite_match.bib_number}\">" +
|
27
|
-
cite_text + '</a></li>'
|
28
|
-
end
|
29
|
-
out_lines.push '</ol>'
|
30
|
-
end
|
31
|
-
|
32
|
-
def strip_extra_papers_brackets(line)
|
33
|
-
line.gsub!(/\{|\}/, '')
|
34
|
-
end
|
35
|
-
|
36
|
-
def style_line(line, citations)
|
37
|
-
processed_line = ''
|
38
|
-
pos_off_set = 0
|
39
|
-
citations.each do |cite_match|
|
40
|
-
if cite_match[0].is_a?(CiteMatch)
|
41
|
-
output, offset = single_cite(cite_match[0],
|
42
|
-
cite_match[1] - pos_off_set, line)
|
43
|
-
pos_off_set += offset
|
44
|
-
|
45
|
-
elsif cite_match[0].is_a? Array
|
46
|
-
output = multi_cite(cite_match, line, pos_off_set)
|
47
|
-
end
|
48
|
-
if output.nil?
|
49
|
-
puts "wait"
|
50
|
-
end
|
51
|
-
processed_line += output
|
52
|
-
end
|
53
|
-
processed_line += line
|
54
|
-
end
|
55
|
-
|
56
|
-
def multi_cite(cite_match_array, line, pos_offset)
|
57
|
-
output_line = @open_tag
|
58
|
-
cite_match_array.each_with_index do |cite_match, index|
|
59
|
-
citation, pos = cite_match
|
60
|
-
output, off_set = single_cite(citation, pos - pos_offset, line)
|
61
|
-
output_line += output
|
62
|
-
output_line += @multi_separator unless index == cite_match.size - 1
|
63
|
-
pos_offset += off_set
|
64
|
-
end
|
65
|
-
output_line += @close_tag
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
def single_cite(citation, pos, line)
|
70
|
-
key = citation.key
|
71
|
-
pos == 0 ? before_cite = '' : before_cite = line.slice!(0..pos - 1)
|
72
|
-
cite = line.slice!(0..key.length - 1)
|
73
|
-
off_set = before_cite.length + cite.length
|
74
|
-
in_text_citation = "<sup><a href = \"#bibliography_#{citation.bib_number}\
|
75
|
-
\">#{citation.bib_number}</a></sup>"
|
76
|
-
output_line = before_cite + in_text_citation
|
77
|
-
[output_line, off_set]
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|