card 1.18.0 → 1.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/card.gemspec +20 -16
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
- data/db/schema.rb +110 -92
- data/lib/card.rb +1 -0
- data/lib/card/content.rb +4 -73
- data/lib/card/content/chunk.rb +119 -0
- data/lib/card/content/parser.rb +75 -0
- data/lib/card/diff.rb +25 -398
- data/lib/card/diff/lcs.rb +247 -0
- data/lib/card/diff/result.rb +131 -0
- data/lib/card/director_register.rb +5 -0
- data/lib/card/query/attributes.rb +19 -13
- data/lib/card/set/event.rb +2 -1
- data/lib/card/set_pattern.rb +4 -2
- data/lib/card/spec_helper.rb +7 -1
- data/lib/card/stage_director.rb +33 -5
- data/lib/card/subcards.rb +11 -3
- data/lib/card/subdirector_array.rb +14 -1
- data/lib/cardio.rb +8 -5
- data/mod/01_core/chunk/include.rb +2 -2
- data/mod/01_core/chunk/link.rb +3 -3
- data/mod/01_core/chunk/literal.rb +20 -14
- data/mod/01_core/chunk/query_reference.rb +2 -2
- data/mod/01_core/chunk/reference.rb +47 -38
- data/mod/01_core/chunk/uri.rb +17 -13
- data/mod/01_core/format/html_format.rb +0 -2
- data/mod/01_core/set/all/actify.rb +12 -1
- data/mod/01_core/set/all/collection.rb +4 -4
- data/mod/01_core/set/all/fetch.rb +0 -27
- data/mod/01_core/set/all/name.rb +33 -12
- data/mod/01_core/set/all/pattern.rb +2 -6
- data/mod/01_core/set/all/phases.rb +0 -1
- data/mod/01_core/set/all/references.rb +2 -2
- data/mod/01_core/set/all/rules.rb +10 -3
- data/mod/01_core/set/all/tracked_attributes.rb +0 -1
- data/mod/01_core/set/all/type.rb +0 -14
- data/mod/01_core/spec/chunk/literal_spec.rb +1 -1
- data/mod/01_core/spec/chunk/uri_spec.rb +204 -201
- data/mod/01_core/spec/set/all/type_spec.rb +3 -1
- data/mod/01_history/lib/card/action.rb +7 -9
- data/mod/01_history/set/all/history.rb +6 -1
- data/mod/02_basic_types/set/all/all_csv.rb +1 -1
- data/mod/02_basic_types/set/type/pointer.rb +20 -9
- data/mod/03_machines/lib/javascript/wagn.js.coffee +1 -1
- data/mod/04_settings/set/right/structure.rb +7 -1
- data/mod/05_email/set/right/follow.rb +22 -22
- data/mod/05_email/set/type_plus_right/user/follow.rb +25 -26
- data/mod/05_standard/set/all/rich_html/wrapper.rb +12 -6
- data/mod/05_standard/set/rstar/rules_editor.rb +6 -4
- data/mod/05_standard/set/self/all.rb +0 -10
- data/mod/05_standard/set/self/stats.rb +6 -15
- data/mod/05_standard/set/type/set.rb +0 -6
- data/mod/05_standard/spec/chunk/include_spec.rb +2 -2
- data/mod/05_standard/spec/chunk/link_spec.rb +1 -1
- data/mod/05_standard/spec/chunk/query_reference_spec.rb +5 -4
- data/spec/lib/card/chunk_spec.rb +7 -5
- data/spec/lib/card/content_spec.rb +11 -11
- data/spec/lib/card/diff_spec.rb +4 -4
- data/spec/lib/card/stage_director_spec.rb +56 -0
- data/spec/lib/card/subcards_spec.rb +0 -1
- data/spec/models/card/type_transition_spec.rb +5 -42
- metadata +12 -23
- data/lib/card/chunk.rb +0 -122
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0e96aef9fe8581d7e787b0ad6ed56db1b3ec7d1
|
4
|
+
data.tar.gz: bbdd504c7800d1c372bd4199a293eeeb4e0ad501
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bb8bfa7d9df016796744af64b3361c5abbf5fefe1b10d17f4ae08af370e12600e1e1353da8ed00ae07bc281c484a0fbf458fe51d535e06ff0b49fd2987d58a1
|
7
|
+
data.tar.gz: d0f7b44c9ec0b44118f29a0fab7721402fcdfb397df4396a914243aa5477e18eeefed973fcb1434eb56eb8af6c788104a59178f23fcf10c414b17b1394d4eb38
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.18.
|
1
|
+
1.18.1
|
data/card.gemspec
CHANGED
@@ -1,25 +1,30 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
6
|
-
s.authors
|
7
|
-
|
4
|
+
s.name = 'card'
|
5
|
+
s.version = File.open(File.expand_path('../VERSION', __FILE__)).read.chomp
|
6
|
+
s.authors =
|
7
|
+
['Ethan McCutchen', 'Lewis Hoffman', 'Gerry Gleason', "Philipp Kühl"]
|
8
|
+
s.email = ['info@wagn.org']
|
8
9
|
|
9
10
|
# s.date = '2013-12-20'
|
10
11
|
s.summary = 'an atomic, set-driven content engine'
|
11
|
-
s.description =
|
12
|
+
s.description =
|
13
|
+
'Cards are data atoms grouped into Sets to which Rules can apply. '\
|
14
|
+
'Cards can formatted with Views and transformed with Events.'
|
12
15
|
s.homepage = 'http://wagn.org'
|
13
16
|
s.license = 'GPL'
|
14
17
|
|
15
|
-
s.files = `git ls-files`.split
|
18
|
+
s.files = `git ls-files`.split $INPUT_RECORD_SEPARATOR
|
16
19
|
|
17
20
|
# add submodule files (seed data)
|
18
|
-
`git submodule --quiet foreach pwd`.split
|
21
|
+
morepaths = `git submodule --quiet foreach pwd`.split $OUTPUT_RECORD_SEPARATOR
|
22
|
+
morepaths.each do |submod_path|
|
19
23
|
gem_root = File.expand_path File.dirname(__FILE__)
|
20
24
|
relative_submod_path = submod_path.gsub "#{gem_root}/", ''
|
21
25
|
Dir.chdir(submod_path) do
|
22
|
-
|
26
|
+
morefiles = `git ls-files`.split $OUTPUT_RECORD_SEPARATOR
|
27
|
+
s.files += morefiles.map do |filename|
|
23
28
|
"#{relative_submod_path}/#{filename}"
|
24
29
|
end
|
25
30
|
end
|
@@ -31,15 +36,14 @@ Gem::Specification.new do |s|
|
|
31
36
|
s.required_ruby_version = '>= 1.9.3'
|
32
37
|
|
33
38
|
[
|
34
|
-
|
35
39
|
['smartname', '0.2.3'],
|
36
|
-
|
37
|
-
['activerecord-session_store', '~> 0.1'],
|
38
40
|
['uuid', '~> 2.3'],
|
39
|
-
['carrierwave',
|
41
|
+
['carrierwave', '~> 0.10'],
|
40
42
|
['htmlentities', '~> 4.3'],
|
41
|
-
['mini_magick', '~> 4.2
|
43
|
+
['mini_magick', '~> 4.2'],
|
42
44
|
['recaptcha', '~> 0.4.0'],
|
45
|
+
# 0.4.0 is last version that doesn't require ruby 2.0
|
46
|
+
|
43
47
|
['coderay', '~> 1.0'],
|
44
48
|
['sass', '~> 3.2'],
|
45
49
|
['coffee-script', '~> 2.2'],
|
@@ -47,10 +51,10 @@ Gem::Specification.new do |s|
|
|
47
51
|
|
48
52
|
['haml', '~> 4.0'],
|
49
53
|
['kaminari', '~> 0.16'],
|
50
|
-
['bootstrap-kaminari-views', '~> 0.0.5'],
|
51
|
-
['diff-lcs', '~> 1.2']
|
52
54
|
|
55
|
+
['bootstrap-kaminari-views', '~> 0'],
|
56
|
+
['diff-lcs', '~> 1.2']
|
53
57
|
].each do |dep|
|
54
|
-
s.add_runtime_dependency
|
58
|
+
s.add_runtime_dependency(*dep)
|
55
59
|
end
|
56
60
|
end
|
@@ -57,7 +57,7 @@ class ImportBootstrapLayout < Card::CoreMigration
|
|
57
57
|
# update layouts to have explicit views in nests
|
58
58
|
Card.search(type_id: Card::LayoutTypeID) do |lcard|
|
59
59
|
lcontent = Card::Content.new lcard.content, lcard
|
60
|
-
lcontent.find_chunks(Card::Chunk::Include).each do |nest|
|
60
|
+
lcontent.find_chunks(Card::Content::Chunk::Include).each do |nest|
|
61
61
|
nest.explicit_view = (nest.options[:inc_name] == '_main' ? 'open' : 'core')
|
62
62
|
end
|
63
63
|
lcard.update_attributes! content: lcontent.to_s
|
data/db/schema.rb
CHANGED
@@ -11,121 +11,139 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
15
|
-
|
16
|
-
|
17
|
-
t.integer
|
18
|
-
t.integer
|
19
|
-
t.integer
|
20
|
-
t.
|
21
|
-
t.
|
14
|
+
ActiveRecord::Schema.define(version: 20160122153608) do
|
15
|
+
|
16
|
+
create_table "card_actions", force: :cascade do |t|
|
17
|
+
t.integer "card_id", limit: 4
|
18
|
+
t.integer "card_act_id", limit: 4
|
19
|
+
t.integer "super_action_id", limit: 4
|
20
|
+
t.integer "action_type", limit: 4
|
21
|
+
t.boolean "draft"
|
22
|
+
t.text "comment", limit: 65535
|
22
23
|
end
|
23
24
|
|
24
|
-
add_index
|
25
|
-
add_index
|
25
|
+
add_index "card_actions", ["card_act_id"], name: "card_actions_card_act_id_index", using: :btree
|
26
|
+
add_index "card_actions", ["card_id"], name: "card_actions_card_id_index", using: :btree
|
26
27
|
|
27
|
-
create_table
|
28
|
-
t.integer
|
29
|
-
t.integer
|
30
|
-
t.datetime
|
31
|
-
t.string
|
28
|
+
create_table "card_acts", force: :cascade do |t|
|
29
|
+
t.integer "card_id", limit: 4
|
30
|
+
t.integer "actor_id", limit: 4
|
31
|
+
t.datetime "acted_at"
|
32
|
+
t.string "ip_address", limit: 255
|
32
33
|
end
|
33
34
|
|
34
|
-
add_index
|
35
|
-
add_index
|
36
|
-
add_index
|
35
|
+
add_index "card_acts", ["acted_at"], name: "acts_acted_at_index", using: :btree
|
36
|
+
add_index "card_acts", ["actor_id"], name: "card_acts_actor_id_index", using: :btree
|
37
|
+
add_index "card_acts", ["card_id"], name: "card_acts_card_id_index", using: :btree
|
37
38
|
|
38
|
-
create_table
|
39
|
-
t.integer
|
40
|
-
t.integer
|
41
|
-
t.text
|
39
|
+
create_table "card_changes", force: :cascade do |t|
|
40
|
+
t.integer "card_action_id", limit: 4
|
41
|
+
t.integer "field", limit: 4
|
42
|
+
t.text "value", limit: 16777215
|
42
43
|
end
|
43
44
|
|
44
|
-
add_index
|
45
|
+
add_index "card_changes", ["card_action_id"], name: "card_changes_card_action_id_index", using: :btree
|
45
46
|
|
46
|
-
create_table
|
47
|
-
t.integer
|
48
|
-
t.string
|
49
|
-
t.integer
|
50
|
-
t.string
|
51
|
-
t.integer
|
47
|
+
create_table "card_references", force: :cascade do |t|
|
48
|
+
t.integer "referer_id", limit: 4, default: 0, null: false
|
49
|
+
t.string "referee_key", limit: 255, default: "", null: false
|
50
|
+
t.integer "referee_id", limit: 4
|
51
|
+
t.string "ref_type", limit: 1, default: "", null: false
|
52
|
+
t.integer "present", limit: 4
|
52
53
|
end
|
53
54
|
|
54
|
-
add_index
|
55
|
-
add_index
|
56
|
-
add_index
|
57
|
-
add_index
|
55
|
+
add_index "card_references", ["ref_type"], name: "card_references_ref_type_index", using: :btree
|
56
|
+
add_index "card_references", ["referee_id"], name: "card_references_referee_id_index", using: :btree
|
57
|
+
add_index "card_references", ["referee_key"], name: "card_references_referee_key_index", using: :btree
|
58
|
+
add_index "card_references", ["referer_id"], name: "card_references_referer_id_index", using: :btree
|
58
59
|
|
59
|
-
create_table
|
60
|
-
t.datetime
|
61
|
-
t.integer
|
62
|
-
t.integer
|
63
|
-
t.text
|
60
|
+
create_table "card_revisions", force: :cascade do |t|
|
61
|
+
t.datetime "created_at", null: false
|
62
|
+
t.integer "card_id", limit: 4, null: false
|
63
|
+
t.integer "creator_id", limit: 4, null: false
|
64
|
+
t.text "content", limit: 65535, null: false
|
64
65
|
end
|
65
66
|
|
66
|
-
add_index
|
67
|
-
add_index
|
68
|
-
|
69
|
-
create_table
|
70
|
-
t.
|
71
|
-
t.
|
72
|
-
t.
|
73
|
-
t.integer
|
74
|
-
t.
|
75
|
-
t.integer
|
76
|
-
t.
|
77
|
-
t.
|
78
|
-
t.
|
79
|
-
t.
|
80
|
-
t.
|
81
|
-
t.
|
82
|
-
t.
|
83
|
-
t.
|
84
|
-
t.integer
|
85
|
-
t.text
|
67
|
+
add_index "card_revisions", ["card_id"], name: "revisions_card_id_index", using: :btree
|
68
|
+
add_index "card_revisions", ["creator_id"], name: "revisions_created_by_index", using: :btree
|
69
|
+
|
70
|
+
create_table "cards", force: :cascade do |t|
|
71
|
+
t.integer "left_id", limit: 4
|
72
|
+
t.datetime "created_at", null: false
|
73
|
+
t.datetime "updated_at", null: false
|
74
|
+
t.integer "current_revision_id", limit: 4
|
75
|
+
t.string "name", limit: 255, null: false
|
76
|
+
t.integer "creator_id", limit: 4, null: false
|
77
|
+
t.integer "updater_id", limit: 4, null: false
|
78
|
+
t.integer "right_id", limit: 4
|
79
|
+
t.string "key", limit: 255, null: false
|
80
|
+
t.boolean "trash", null: false
|
81
|
+
t.integer "references_expired", limit: 4
|
82
|
+
t.string "codename", limit: 255
|
83
|
+
t.string "read_rule_class", limit: 255
|
84
|
+
t.integer "read_rule_id", limit: 4
|
85
|
+
t.integer "type_id", limit: 4, null: false
|
86
|
+
t.text "db_content", limit: 16777215
|
86
87
|
end
|
87
88
|
|
88
|
-
add_index
|
89
|
-
add_index
|
90
|
-
add_index
|
91
|
-
add_index
|
92
|
-
add_index
|
93
|
-
add_index
|
94
|
-
add_index
|
95
|
-
add_index
|
96
|
-
|
97
|
-
create_table
|
98
|
-
t.
|
89
|
+
add_index "cards", ["created_at"], name: "cards_created_at_index", using: :btree
|
90
|
+
add_index "cards", ["key"], name: "cards_key_index", unique: true, using: :btree
|
91
|
+
add_index "cards", ["left_id"], name: "cards_left_id_index", using: :btree
|
92
|
+
add_index "cards", ["name"], name: "cards_name_index", using: :btree
|
93
|
+
add_index "cards", ["read_rule_id"], name: "cards_read_rule_id_index", using: :btree
|
94
|
+
add_index "cards", ["right_id"], name: "cards_right_id_index", using: :btree
|
95
|
+
add_index "cards", ["type_id"], name: "cards_type_id_index", using: :btree
|
96
|
+
add_index "cards", ["updated_at"], name: "cards_updated_at_index", using: :btree
|
97
|
+
|
98
|
+
create_table "delayed_jobs", force: :cascade do |t|
|
99
|
+
t.integer "priority", limit: 4, default: 0, null: false
|
100
|
+
t.integer "attempts", limit: 4, default: 0, null: false
|
101
|
+
t.text "handler", limit: 65535, null: false
|
102
|
+
t.text "last_error", limit: 65535
|
103
|
+
t.datetime "run_at"
|
104
|
+
t.datetime "locked_at"
|
105
|
+
t.datetime "failed_at"
|
106
|
+
t.string "locked_by", limit: 255
|
107
|
+
t.string "queue", limit: 255
|
108
|
+
t.datetime "created_at"
|
109
|
+
t.datetime "updated_at"
|
99
110
|
end
|
100
111
|
|
101
|
-
add_index
|
112
|
+
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
|
102
113
|
|
103
|
-
create_table
|
104
|
-
t.string
|
114
|
+
create_table "schema_migrations_core_cards", id: false, force: :cascade do |t|
|
115
|
+
t.string "version", limit: 255, null: false
|
105
116
|
end
|
106
117
|
|
107
|
-
add_index
|
118
|
+
add_index "schema_migrations_core_cards", ["version"], name: "unique_schema_migrations_cards", unique: true, using: :btree
|
108
119
|
|
109
|
-
create_table
|
110
|
-
t.string
|
111
|
-
t.text 'data', limit: 65_535
|
112
|
-
t.datetime 'updated_at'
|
120
|
+
create_table "schema_migrations_deck_cards", id: false, force: :cascade do |t|
|
121
|
+
t.string "version", limit: 255, null: false
|
113
122
|
end
|
114
123
|
|
115
|
-
add_index
|
116
|
-
|
117
|
-
create_table
|
118
|
-
t.string
|
119
|
-
t.
|
120
|
-
t.
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
t.
|
127
|
-
t.string
|
128
|
-
t.
|
129
|
-
t.
|
124
|
+
add_index "schema_migrations_deck_cards", ["version"], name: "unique_schema_migrations_deck_cards", unique: true, using: :btree
|
125
|
+
|
126
|
+
create_table "sessions", force: :cascade do |t|
|
127
|
+
t.string "session_id", limit: 255
|
128
|
+
t.text "data", limit: 65535
|
129
|
+
t.datetime "updated_at"
|
130
|
+
end
|
131
|
+
|
132
|
+
add_index "sessions", ["session_id"], name: "sessions_session_id_index", using: :btree
|
133
|
+
|
134
|
+
create_table "users", force: :cascade do |t|
|
135
|
+
t.string "login", limit: 40
|
136
|
+
t.string "email", limit: 100
|
137
|
+
t.string "crypted_password", limit: 40
|
138
|
+
t.string "salt", limit: 42
|
139
|
+
t.datetime "created_at"
|
140
|
+
t.datetime "updated_at"
|
141
|
+
t.string "password_reset_code", limit: 40
|
142
|
+
t.string "status", limit: 255, default: "request"
|
143
|
+
t.integer "invite_sender_id", limit: 4
|
144
|
+
t.string "identity_url", limit: 255
|
145
|
+
t.integer "card_id", limit: 4, null: false
|
146
|
+
t.integer "account_id", limit: 4, null: false
|
130
147
|
end
|
148
|
+
|
131
149
|
end
|
data/lib/card.rb
CHANGED
@@ -35,6 +35,7 @@ class Card < ActiveRecord::Base
|
|
35
35
|
require_dependency 'card/stage_director'
|
36
36
|
require_dependency 'card/director_register'
|
37
37
|
|
38
|
+
|
38
39
|
has_many :references_in, class_name: :Reference, foreign_key: :referee_id
|
39
40
|
has_many :references_out, class_name: :Reference, foreign_key: :referer_id
|
40
41
|
has_many :acts, -> { order :id }
|
data/lib/card/content.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
|
4
|
-
require_dependency 'card/
|
3
|
+
require_dependency 'card/content/chunk'
|
4
|
+
require_dependency 'card/content/parser'
|
5
5
|
|
6
6
|
class Card
|
7
7
|
class Content < SimpleDelegator
|
@@ -16,8 +16,8 @@ class Card
|
|
16
16
|
end
|
17
17
|
@opts = opts || {}
|
18
18
|
|
19
|
-
|
20
|
-
super content
|
19
|
+
@chunks = Parser.new(chunk_list).parse(content, self)
|
20
|
+
super(@chunks.any? ? @chunks : content)
|
21
21
|
end
|
22
22
|
|
23
23
|
def card
|
@@ -62,75 +62,6 @@ class Card
|
|
62
62
|
self
|
63
63
|
end
|
64
64
|
|
65
|
-
def parse_content content
|
66
|
-
@chunks = []
|
67
|
-
|
68
|
-
if content.is_a? String
|
69
|
-
position = last_position = 0
|
70
|
-
prefix_regexp = Chunk.get_prefix_regexp chunk_list
|
71
|
-
interval_string = ''
|
72
|
-
|
73
|
-
while (prefix_match = content[position..-1].match(prefix_regexp))
|
74
|
-
prefix = prefix_match[0]
|
75
|
-
# prefix of matched chunk
|
76
|
-
chunk_start = prefix_match.begin(0) + position
|
77
|
-
# content index of beginning of chunk
|
78
|
-
if prefix_match.begin(0) > 0
|
79
|
-
# if matched chunk is not beginning of test string
|
80
|
-
interval_string += content[position..chunk_start - 1]
|
81
|
-
# hold onto the non-chunk part of the string
|
82
|
-
end
|
83
|
-
|
84
|
-
chunk_class = Chunk.find_class_by_prefix prefix
|
85
|
-
# get the chunk class from the prefix
|
86
|
-
match, offset =
|
87
|
-
chunk_class.full_match content[chunk_start..-1], prefix
|
88
|
-
# see whether the full chunk actually matches
|
89
|
-
# (as opposed to bogus prefix)
|
90
|
-
context_ok = chunk_class.context_ok? content, chunk_start
|
91
|
-
# make sure there aren't contextual reasons for ignoring this chunk
|
92
|
-
position = chunk_start
|
93
|
-
# move scanning position up to beginning of chunk
|
94
|
-
|
95
|
-
if match
|
96
|
-
# we have a chunk match
|
97
|
-
position += (match.end(0) - offset.to_i)
|
98
|
-
# move scanning position up to end of chunk
|
99
|
-
if context_ok
|
100
|
-
@chunks << interval_string unless interval_string.empty?
|
101
|
-
# add the nonchunk string to the chunk list
|
102
|
-
@chunks << chunk_class.new(match, self)
|
103
|
-
# add the chunk to the chunk list
|
104
|
-
interval_string = ''
|
105
|
-
# reset interval string for next go-round
|
106
|
-
last_position = position
|
107
|
-
# note that the end of the chunk was the last place where a
|
108
|
-
# chunk was found (so far)
|
109
|
-
end
|
110
|
-
else
|
111
|
-
position += 1
|
112
|
-
# no match. look at the next character
|
113
|
-
end
|
114
|
-
|
115
|
-
next unless !match || !context_ok
|
116
|
-
interval_string += content[chunk_start..position - 1]
|
117
|
-
# moving beyond the alleged chunk.
|
118
|
-
# append failed string to "nonchunk" string
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
if chunks.any?
|
123
|
-
if last_position < content.size
|
124
|
-
remainder = content[last_position..-1]
|
125
|
-
# handle any leftover nonchunk string at the end of content
|
126
|
-
@chunks << remainder
|
127
|
-
end
|
128
|
-
chunks
|
129
|
-
else
|
130
|
-
content
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
65
|
ALLOWED_TAGS = {}
|
135
66
|
%w(
|
136
67
|
br i b pre cite caption strong em ins sup sub del ol hr ul li p
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'uri/common'
|
4
|
+
|
5
|
+
class Card #::Content
|
6
|
+
class Content < SimpleDelegator
|
7
|
+
# A chunk is a pattern of text that can be protected
|
8
|
+
# and interrogated by a format. Each Chunk class has a
|
9
|
+
# +pattern+ that states what sort of text it matches.
|
10
|
+
# Chunks are initalized by passing in the result of a
|
11
|
+
# match by its pattern.
|
12
|
+
module Chunk
|
13
|
+
mattr_accessor :raw_list, :prefix_regexp_by_list, :prefix_map
|
14
|
+
@@raw_list = {}
|
15
|
+
@@prefix_regexp_by_list = {}
|
16
|
+
@@prefix_map = {}
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def register_class klass, hash
|
20
|
+
klass.config = hash.merge class: klass
|
21
|
+
prefix_index = hash[:idx_char] || :default
|
22
|
+
# ^ this is gross and needs to be moved out.
|
23
|
+
prefix_map[prefix_index] = klass.config
|
24
|
+
end
|
25
|
+
|
26
|
+
def register_list key, list
|
27
|
+
raw_list[key] = list
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_class_by_prefix prefix
|
31
|
+
config = prefix_map[prefix[0, 1]] ||
|
32
|
+
prefix_map[prefix[-1, 1]] ||
|
33
|
+
prefix_map[:default]
|
34
|
+
# prefix identified by first character, last character, or default.
|
35
|
+
# a little ugly...
|
36
|
+
config[:class]
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_prefix_regexp chunk_list_key
|
40
|
+
prefix_regexp_by_list[chunk_list_key] ||= begin
|
41
|
+
prefix_res = raw_list[chunk_list_key].map do |chunkname|
|
42
|
+
chunk_class = const_get chunkname
|
43
|
+
chunk_class.config[:prefix_re]
|
44
|
+
end
|
45
|
+
/(?:#{ prefix_res * '|' })/m
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# not sure whether this is best place. Could really happen almost anywhere
|
51
|
+
# (even before chunk classes are loaded).
|
52
|
+
register_list :default, [
|
53
|
+
:URI, :HostURI, :EmailURI, :EscapedLiteral, :Include, :Link
|
54
|
+
]
|
55
|
+
register_list :references, [:EscapedLiteral, :Include, :Link]
|
56
|
+
register_list :nest_only, [:Include]
|
57
|
+
register_list :query, [:QueryReference]
|
58
|
+
|
59
|
+
class Abstract
|
60
|
+
class_attribute :config
|
61
|
+
attr_reader :text, :process_chunk
|
62
|
+
|
63
|
+
class << self
|
64
|
+
# if the prefix regex matched check that chunk against the full regex
|
65
|
+
def full_match content, prefix=nil
|
66
|
+
content.match full_re(prefix)
|
67
|
+
end
|
68
|
+
|
69
|
+
def full_re _prefix
|
70
|
+
config[:full_re]
|
71
|
+
end
|
72
|
+
|
73
|
+
def context_ok? _content, _chunk_start
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def reference_code
|
79
|
+
'I'
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize match, content
|
83
|
+
@text = match[0]
|
84
|
+
@processed = nil
|
85
|
+
@content = content
|
86
|
+
interpret match, content
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
def interpret _match_string, _content, _params
|
91
|
+
Rails.logger.info 'no #interpret method found for chunk class: ' \
|
92
|
+
"#{self.class}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def format
|
96
|
+
@content.format
|
97
|
+
end
|
98
|
+
|
99
|
+
def card
|
100
|
+
@content.card
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
@process_chunk || @processed || @text
|
105
|
+
end
|
106
|
+
|
107
|
+
def inspect
|
108
|
+
"<##{self.class}##{self}>"
|
109
|
+
end
|
110
|
+
|
111
|
+
def as_json _options={}
|
112
|
+
@process_chunk || @processed ||
|
113
|
+
"not rendered #{self.class}, #{card && card.name}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
Card::Loader.load_chunks
|
119
|
+
end
|