hard_citer 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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[![Gem Version](https://badge.fury.io/rb/hard_citer.png)](http://badge.fury.io/rb/hard_citer)[![Coverage Status](https://coveralls.io/repos/mcordell/hard_citer/badge.png?branch=master)](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
|