card 1.18.0 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +20 -16
  4. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  5. data/db/schema.rb +110 -92
  6. data/lib/card.rb +1 -0
  7. data/lib/card/content.rb +4 -73
  8. data/lib/card/content/chunk.rb +119 -0
  9. data/lib/card/content/parser.rb +75 -0
  10. data/lib/card/diff.rb +25 -398
  11. data/lib/card/diff/lcs.rb +247 -0
  12. data/lib/card/diff/result.rb +131 -0
  13. data/lib/card/director_register.rb +5 -0
  14. data/lib/card/query/attributes.rb +19 -13
  15. data/lib/card/set/event.rb +2 -1
  16. data/lib/card/set_pattern.rb +4 -2
  17. data/lib/card/spec_helper.rb +7 -1
  18. data/lib/card/stage_director.rb +33 -5
  19. data/lib/card/subcards.rb +11 -3
  20. data/lib/card/subdirector_array.rb +14 -1
  21. data/lib/cardio.rb +8 -5
  22. data/mod/01_core/chunk/include.rb +2 -2
  23. data/mod/01_core/chunk/link.rb +3 -3
  24. data/mod/01_core/chunk/literal.rb +20 -14
  25. data/mod/01_core/chunk/query_reference.rb +2 -2
  26. data/mod/01_core/chunk/reference.rb +47 -38
  27. data/mod/01_core/chunk/uri.rb +17 -13
  28. data/mod/01_core/format/html_format.rb +0 -2
  29. data/mod/01_core/set/all/actify.rb +12 -1
  30. data/mod/01_core/set/all/collection.rb +4 -4
  31. data/mod/01_core/set/all/fetch.rb +0 -27
  32. data/mod/01_core/set/all/name.rb +33 -12
  33. data/mod/01_core/set/all/pattern.rb +2 -6
  34. data/mod/01_core/set/all/phases.rb +0 -1
  35. data/mod/01_core/set/all/references.rb +2 -2
  36. data/mod/01_core/set/all/rules.rb +10 -3
  37. data/mod/01_core/set/all/tracked_attributes.rb +0 -1
  38. data/mod/01_core/set/all/type.rb +0 -14
  39. data/mod/01_core/spec/chunk/literal_spec.rb +1 -1
  40. data/mod/01_core/spec/chunk/uri_spec.rb +204 -201
  41. data/mod/01_core/spec/set/all/type_spec.rb +3 -1
  42. data/mod/01_history/lib/card/action.rb +7 -9
  43. data/mod/01_history/set/all/history.rb +6 -1
  44. data/mod/02_basic_types/set/all/all_csv.rb +1 -1
  45. data/mod/02_basic_types/set/type/pointer.rb +20 -9
  46. data/mod/03_machines/lib/javascript/wagn.js.coffee +1 -1
  47. data/mod/04_settings/set/right/structure.rb +7 -1
  48. data/mod/05_email/set/right/follow.rb +22 -22
  49. data/mod/05_email/set/type_plus_right/user/follow.rb +25 -26
  50. data/mod/05_standard/set/all/rich_html/wrapper.rb +12 -6
  51. data/mod/05_standard/set/rstar/rules_editor.rb +6 -4
  52. data/mod/05_standard/set/self/all.rb +0 -10
  53. data/mod/05_standard/set/self/stats.rb +6 -15
  54. data/mod/05_standard/set/type/set.rb +0 -6
  55. data/mod/05_standard/spec/chunk/include_spec.rb +2 -2
  56. data/mod/05_standard/spec/chunk/link_spec.rb +1 -1
  57. data/mod/05_standard/spec/chunk/query_reference_spec.rb +5 -4
  58. data/spec/lib/card/chunk_spec.rb +7 -5
  59. data/spec/lib/card/content_spec.rb +11 -11
  60. data/spec/lib/card/diff_spec.rb +4 -4
  61. data/spec/lib/card/stage_director_spec.rb +56 -0
  62. data/spec/lib/card/subcards_spec.rb +0 -1
  63. data/spec/models/card/type_transition_spec.rb +5 -42
  64. metadata +12 -23
  65. data/lib/card/chunk.rb +0 -122
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8c446c5d4d4690dcdfd3dfec9e7ccd86eb8103d
4
- data.tar.gz: 46449abad4c318e46f01f1785d37d755bbdbcac8
3
+ metadata.gz: e0e96aef9fe8581d7e787b0ad6ed56db1b3ec7d1
4
+ data.tar.gz: bbdd504c7800d1c372bd4199a293eeeb4e0ad501
5
5
  SHA512:
6
- metadata.gz: ff2d853a9eb45e599c82338dc3b9b2bfae8674b38ff61129715bf2082311dc32aa323457d74cadee1ac87d0bad8d225787c403ed7bdbed94d69870b5f253af62
7
- data.tar.gz: c3f805c9e1eea8148e9567ef8fa2f89281a401c9c63677e2a06c5820871be6933bc094f83e3edf4dd43ba57025e193764708331f301b98b14925aec5ebe1f544
6
+ metadata.gz: 2bb8bfa7d9df016796744af64b3361c5abbf5fefe1b10d17f4ae08af370e12600e1e1353da8ed00ae07bc281c484a0fbf458fe51d535e06ff0b49fd2987d58a1
7
+ data.tar.gz: d0f7b44c9ec0b44118f29a0fab7721402fcdfb397df4396a914243aa5477e18eeefed973fcb1434eb56eb8af6c788104a59178f23fcf10c414b17b1394d4eb38
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.18.0
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 = 'card'
5
- s.version = File.open(File.expand_path('../VERSION', __FILE__)).read.chomp
6
- s.authors = ['Ethan McCutchen', 'Lewis Hoffman', 'Gerry Gleason', "Philipp Kühl"]
7
- s.email = ['info@wagn.org']
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 = 'Cards are data atoms that are grouped into Sets to which Rules can apply. Cards can formatted with Views and transformed with Events.'
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($INPUT_RECORD_SEPARATOR)
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($OUTPUT_RECORD_SEPARATOR).each do |submod_path|
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
- s.files += `git ls-files`.split($OUTPUT_RECORD_SEPARATOR).map do |filename|
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', '~> 0.10'],
41
+ ['carrierwave', '~> 0.10'],
40
42
  ['htmlentities', '~> 4.3'],
41
- ['mini_magick', '~> 4.2.10'],
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 *dep
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: 20_160_122_153_608) do
15
- create_table 'card_actions', force: :cascade do |t|
16
- t.integer 'card_id', limit: 4
17
- t.integer 'card_act_id', limit: 4
18
- t.integer 'super_action_id', limit: 4
19
- t.integer 'action_type', limit: 4
20
- t.boolean 'draft'
21
- t.text 'comment', limit: 65_535
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 'card_actions', ['card_act_id'], name: 'card_actions_card_act_id_index', using: :btree
25
- add_index 'card_actions', ['card_id'], name: 'card_actions_card_id_index', using: :btree
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 'card_acts', force: :cascade do |t|
28
- t.integer 'card_id', limit: 4
29
- t.integer 'actor_id', limit: 4
30
- t.datetime 'acted_at'
31
- t.string 'ip_address', limit: 255
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 'card_acts', ['acted_at'], name: 'acts_acted_at_index', using: :btree
35
- add_index 'card_acts', ['actor_id'], name: 'card_acts_actor_id_index', using: :btree
36
- add_index 'card_acts', ['card_id'], name: 'card_acts_card_id_index', using: :btree
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 'card_changes', force: :cascade do |t|
39
- t.integer 'card_action_id', limit: 4
40
- t.integer 'field', limit: 4
41
- t.text 'value', limit: 16_777_215
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 'card_changes', ['card_action_id'], name: 'card_changes_card_action_id_index', using: :btree
45
+ add_index "card_changes", ["card_action_id"], name: "card_changes_card_action_id_index", using: :btree
45
46
 
46
- create_table 'card_references', force: :cascade do |t|
47
- t.integer 'referer_id', limit: 4, default: 0, null: false
48
- t.string 'referee_key', limit: 255, default: '', null: false
49
- t.integer 'referee_id', limit: 4
50
- t.string 'ref_type', limit: 1, default: '', null: false
51
- t.integer 'present', limit: 4
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 'card_references', ['ref_type'], name: 'card_references_ref_type_index', using: :btree
55
- add_index 'card_references', ['referee_id'], name: 'card_references_referee_id_index', using: :btree
56
- add_index 'card_references', ['referee_key'], name: 'card_references_referee_key_index', using: :btree
57
- add_index 'card_references', ['referer_id'], name: 'card_references_referer_id_index', using: :btree
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 'card_revisions', force: :cascade do |t|
60
- t.datetime 'created_at', null: false
61
- t.integer 'card_id', limit: 4, null: false
62
- t.integer 'creator_id', limit: 4, null: false
63
- t.text 'content', limit: 65_535, null: false
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 'card_revisions', ['card_id'], name: 'revisions_card_id_index', using: :btree
67
- add_index 'card_revisions', ['creator_id'], name: 'revisions_created_by_index', using: :btree
68
-
69
- create_table 'cards', force: :cascade do |t|
70
- t.string 'name', limit: 255, null: false
71
- t.string 'key', limit: 255, null: false
72
- t.string 'codename', limit: 255
73
- t.integer 'left_id', limit: 4
74
- t.integer 'right_id', limit: 4
75
- t.integer 'current_revision_id', limit: 4
76
- t.datetime 'created_at', null: false
77
- t.datetime 'updated_at', null: false
78
- t.integer 'creator_id', limit: 4, null: false
79
- t.integer 'updater_id', limit: 4, null: false
80
- t.string 'read_rule_class', limit: 255
81
- t.integer 'read_rule_id', limit: 4
82
- t.integer 'references_expired', limit: 4
83
- t.boolean 'trash', null: false
84
- t.integer 'type_id', limit: 4, null: false
85
- t.text 'db_content', limit: 16_777_215
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 'cards', ['created_at'], name: 'cards_created_at_index', using: :btree
89
- add_index 'cards', ['key'], name: 'cards_key_index', unique: true, using: :btree
90
- add_index 'cards', ['left_id'], name: 'cards_left_id_index', using: :btree
91
- add_index 'cards', ['name'], name: 'cards_name_index', using: :btree
92
- add_index 'cards', ['read_rule_id'], name: 'cards_read_rule_id_index', using: :btree
93
- add_index 'cards', ['right_id'], name: 'cards_right_id_index', using: :btree
94
- add_index 'cards', ['type_id'], name: 'cards_type_id_index', using: :btree
95
- add_index 'cards', ['updated_at'], name: 'cards_updated_at_index', using: :btree
96
-
97
- create_table 'schema_migrations_core_cards', id: false, force: :cascade do |t|
98
- t.string 'version', limit: 255, null: false
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 'schema_migrations_core_cards', ['version'], name: 'unique_schema_migrations_cards', unique: true, using: :btree
112
+ add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
102
113
 
103
- create_table 'schema_migrations_deck_cards', id: false, force: :cascade do |t|
104
- t.string 'version', limit: 255, null: false
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 'schema_migrations_deck_cards', ['version'], name: 'unique_schema_migrations_deck_cards', unique: true, using: :btree
118
+ add_index "schema_migrations_core_cards", ["version"], name: "unique_schema_migrations_cards", unique: true, using: :btree
108
119
 
109
- create_table 'sessions', force: :cascade do |t|
110
- t.string 'session_id', limit: 255
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 'sessions', ['session_id'], name: 'sessions_session_id_index', using: :btree
116
-
117
- create_table 'users', force: :cascade do |t|
118
- t.string 'login', limit: 40
119
- t.string 'email', limit: 100
120
- t.string 'crypted_password', limit: 40
121
- t.string 'salt', limit: 42
122
- t.datetime 'created_at'
123
- t.datetime 'updated_at'
124
- t.string 'password_reset_code', limit: 40
125
- t.string 'status', limit: 255, default: 'request'
126
- t.integer 'invite_sender_id', limit: 4
127
- t.string 'identity_url', limit: 255
128
- t.integer 'card_id', limit: 4, null: false
129
- t.integer 'account_id', limit: 4, null: false
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
- # TODO: move Card::Chunk to Card::Content::Chunk...
4
- require_dependency 'card/chunk'
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
- content = parse_content content unless content.is_a?(Array)
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