card 1.18.0 → 1.18.1
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 +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
|