bulkrax 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +205 -0
  3. data/README.md +202 -0
  4. data/Rakefile +42 -0
  5. data/app/assets/config/bulkrax_manifest.js +2 -0
  6. data/app/assets/javascripts/bulkrax/application.js +14 -0
  7. data/app/assets/javascripts/bulkrax/bulkrax.js +11 -0
  8. data/app/assets/javascripts/bulkrax/entries.js +15 -0
  9. data/app/assets/javascripts/bulkrax/exporters.js +60 -0
  10. data/app/assets/javascripts/bulkrax/importers.js.erb +166 -0
  11. data/app/assets/stylesheets/bulkrax/accordion.scss +40 -0
  12. data/app/assets/stylesheets/bulkrax/application.css +15 -0
  13. data/app/assets/stylesheets/bulkrax/coderay.scss +264 -0
  14. data/app/assets/stylesheets/bulkrax/import_export.scss +37 -0
  15. data/app/controllers/bulkrax/application_controller.rb +8 -0
  16. data/app/controllers/bulkrax/entries_controller.rb +44 -0
  17. data/app/controllers/bulkrax/exporters_controller.rb +125 -0
  18. data/app/controllers/bulkrax/importers_controller.rb +315 -0
  19. data/app/controllers/concerns/bulkrax/api.rb +29 -0
  20. data/app/factories/bulkrax/object_factory.rb +230 -0
  21. data/app/helpers/bulkrax/application_helper.rb +15 -0
  22. data/app/helpers/bulkrax/exporters_helper.rb +6 -0
  23. data/app/helpers/bulkrax/importers_helper.rb +13 -0
  24. data/app/helpers/bulkrax/validation_helper.rb +153 -0
  25. data/app/jobs/bulkrax/application_job.rb +6 -0
  26. data/app/jobs/bulkrax/child_relationships_job.rb +128 -0
  27. data/app/jobs/bulkrax/delete_work_job.rb +16 -0
  28. data/app/jobs/bulkrax/download_cloud_file_job.rb +18 -0
  29. data/app/jobs/bulkrax/export_work_job.rb +37 -0
  30. data/app/jobs/bulkrax/exporter_job.rb +14 -0
  31. data/app/jobs/bulkrax/import_work_collection_job.rb +41 -0
  32. data/app/jobs/bulkrax/import_work_job.rb +32 -0
  33. data/app/jobs/bulkrax/importer_job.rb +26 -0
  34. data/app/mailers/bulkrax/application_mailer.rb +8 -0
  35. data/app/matchers/bulkrax/application_matcher.rb +113 -0
  36. data/app/matchers/bulkrax/bagit_matcher.rb +6 -0
  37. data/app/matchers/bulkrax/csv_matcher.rb +6 -0
  38. data/app/matchers/bulkrax/oai_matcher.rb +6 -0
  39. data/app/models/bulkrax/application_record.rb +7 -0
  40. data/app/models/bulkrax/csv_collection_entry.rb +19 -0
  41. data/app/models/bulkrax/csv_entry.rb +163 -0
  42. data/app/models/bulkrax/entry.rb +104 -0
  43. data/app/models/bulkrax/exporter.rb +122 -0
  44. data/app/models/bulkrax/exporter_run.rb +7 -0
  45. data/app/models/bulkrax/import_failed.rb +13 -0
  46. data/app/models/bulkrax/importer.rb +155 -0
  47. data/app/models/bulkrax/importer_run.rb +8 -0
  48. data/app/models/bulkrax/oai_dc_entry.rb +6 -0
  49. data/app/models/bulkrax/oai_entry.rb +74 -0
  50. data/app/models/bulkrax/oai_qualified_dc_entry.rb +6 -0
  51. data/app/models/bulkrax/oai_set_entry.rb +19 -0
  52. data/app/models/bulkrax/rdf_collection_entry.rb +19 -0
  53. data/app/models/bulkrax/rdf_entry.rb +90 -0
  54. data/app/models/bulkrax/status.rb +25 -0
  55. data/app/models/bulkrax/xml_entry.rb +73 -0
  56. data/app/models/concerns/bulkrax/download_behavior.rb +61 -0
  57. data/app/models/concerns/bulkrax/errored_entries.rb +45 -0
  58. data/app/models/concerns/bulkrax/export_behavior.rb +58 -0
  59. data/app/models/concerns/bulkrax/file_factory.rb +140 -0
  60. data/app/models/concerns/bulkrax/has_local_processing.rb +7 -0
  61. data/app/models/concerns/bulkrax/has_matchers.rb +155 -0
  62. data/app/models/concerns/bulkrax/import_behavior.rb +90 -0
  63. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +34 -0
  64. data/app/models/concerns/bulkrax/status_info.rb +56 -0
  65. data/app/parsers/bulkrax/application_parser.rb +299 -0
  66. data/app/parsers/bulkrax/bagit_parser.rb +157 -0
  67. data/app/parsers/bulkrax/csv_parser.rb +266 -0
  68. data/app/parsers/bulkrax/oai_dc_parser.rb +130 -0
  69. data/app/parsers/bulkrax/oai_qualified_dc_parser.rb +9 -0
  70. data/app/parsers/bulkrax/xml_parser.rb +103 -0
  71. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +19 -0
  72. data/app/views/bulkrax/entries/_raw_metadata.html.erb +19 -0
  73. data/app/views/bulkrax/entries/show.html.erb +63 -0
  74. data/app/views/bulkrax/exporters/_form.html.erb +120 -0
  75. data/app/views/bulkrax/exporters/edit.html.erb +23 -0
  76. data/app/views/bulkrax/exporters/index.html.erb +67 -0
  77. data/app/views/bulkrax/exporters/new.html.erb +23 -0
  78. data/app/views/bulkrax/exporters/show.html.erb +124 -0
  79. data/app/views/bulkrax/importers/_bagit_fields.html.erb +54 -0
  80. data/app/views/bulkrax/importers/_browse_everything.html.erb +12 -0
  81. data/app/views/bulkrax/importers/_csv_fields.html.erb +39 -0
  82. data/app/views/bulkrax/importers/_edit_form_buttons.html.erb +16 -0
  83. data/app/views/bulkrax/importers/_form.html.erb +35 -0
  84. data/app/views/bulkrax/importers/_oai_fields.html.erb +42 -0
  85. data/app/views/bulkrax/importers/_xml_fields.html.erb +60 -0
  86. data/app/views/bulkrax/importers/edit.html.erb +20 -0
  87. data/app/views/bulkrax/importers/index.html.erb +77 -0
  88. data/app/views/bulkrax/importers/new.html.erb +25 -0
  89. data/app/views/bulkrax/importers/show.html.erb +175 -0
  90. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +37 -0
  91. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +52 -0
  92. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +39 -0
  93. data/app/views/hyrax/dashboard/sidebar/_bulkrax_sidebar_additions.html.erb +6 -0
  94. data/app/views/hyrax/dashboard/sidebar/_repository_content.html.erb +19 -0
  95. data/app/views/layouts/bulkrax/application.html.erb +14 -0
  96. data/config/locales/bulkrax.en.yml +36 -0
  97. data/config/routes.rb +18 -0
  98. data/db/migrate/20181011230201_create_bulkrax_importers.rb +18 -0
  99. data/db/migrate/20181011230228_create_bulkrax_importer_runs.rb +16 -0
  100. data/db/migrate/20190325183136_create_bulkrax_entries.rb +16 -0
  101. data/db/migrate/20190601221109_add_status_to_entry.rb +9 -0
  102. data/db/migrate/20190715161939_add_collections_to_importer_runs.rb +6 -0
  103. data/db/migrate/20190715162044_change_collection_ids_on_entries.rb +5 -0
  104. data/db/migrate/20190729124607_create_bulkrax_exporters.rb +19 -0
  105. data/db/migrate/20190729134158_create_bulkrax_exporter_runs.rb +14 -0
  106. data/db/migrate/20190731114016_change_importer_and_exporter_to_polymorphic.rb +12 -0
  107. data/db/migrate/20191203225129_add_total_collection_records_to_importer_runs.rb +5 -0
  108. data/db/migrate/20191204191623_add_children_to_importer_runs.rb +6 -0
  109. data/db/migrate/20191204223857_change_total_records_to_total_work_entries.rb +6 -0
  110. data/db/migrate/20191212155530_change_entry_last_error.rb +19 -0
  111. data/db/migrate/20200108194557_add_validate_only_to_bulkrax_importers.rb +5 -0
  112. data/db/migrate/20200301232856_add_status_to_importers.rb +9 -0
  113. data/db/migrate/20200312190638_remove_foreign_key_from_bulkrax_entries.rb +5 -0
  114. data/db/migrate/20200326235838_add_status_to_exporters.rb +7 -0
  115. data/db/migrate/20200601204556_add_invalid_record_to_importer_run.rb +5 -0
  116. data/db/migrate/20200818055819_create_bulkrax_statuses.rb +18 -0
  117. data/db/migrate/20200819054016_move_to_statuses.rb +30 -0
  118. data/db/migrate/20201106014204_add_date_filter_and_status_to_bulkrax_exporters.rb +7 -0
  119. data/db/migrate/20201117220007_add_workflow_status_to_bulkrax_exporter.rb +5 -0
  120. data/db/migrate/20210806044408_remove_unused_last_error.rb +7 -0
  121. data/db/migrate/20210806065737_increase_text_sizes.rb +12 -0
  122. data/lib/bulkrax.rb +161 -0
  123. data/lib/bulkrax/engine.rb +37 -0
  124. data/lib/bulkrax/version.rb +5 -0
  125. data/lib/generators/bulkrax/install_generator.rb +80 -0
  126. data/lib/generators/bulkrax/templates/README +3 -0
  127. data/lib/generators/bulkrax/templates/app/assets/images/bulkrax/removed.png +0 -0
  128. data/lib/generators/bulkrax/templates/app/models/concerns/bulkrax/has_local_processing.rb +8 -0
  129. data/lib/generators/bulkrax/templates/bin/importer +140 -0
  130. data/lib/generators/bulkrax/templates/config/bulkrax_api.yml +84 -0
  131. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +72 -0
  132. data/lib/tasks/bulkrax_tasks.rake +6 -0
  133. metadata +388 -0
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/bulkrax .js
2
+ //= link_directory ../stylesheets/bulkrax .css
@@ -0,0 +1,14 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+
14
+ //= require_tree .
@@ -0,0 +1,11 @@
1
+ // Global JS file for Bulkrax
2
+
3
+ $(document).on('turbolinks:load ready', function() {
4
+ // Apply to Importer and Exporter views
5
+ $('button#err_toggle').click(function() {
6
+ $('#error_trace').toggle();
7
+ });
8
+ $('button#fm_toggle').click(function() {
9
+ $('#field_mapping').toggle();
10
+ });
11
+ });
@@ -0,0 +1,15 @@
1
+ $( document ).on('turbolinks:load ready', function() {
2
+
3
+ $( "button#entry_error" ).click(function() {
4
+ $( "#error_trace" ).toggle();
5
+ });
6
+
7
+ $( "button#raw_button" ).click(function() {
8
+ $( "#raw_metadata" ).toggle();
9
+ });
10
+
11
+ $( "button#parsed_button" ).click(function() {
12
+ $( "#parsed_metadata" ).toggle();
13
+ });
14
+
15
+ })
@@ -0,0 +1,60 @@
1
+ function hideUnhide(field) {
2
+ var allSources = $('body').find('.export-source-option')
3
+ hide(allSources)
4
+
5
+ if (field.length > 0) {
6
+ var selectedSource = $('.' + field)
7
+ unhideSelected(selectedSource)
8
+ }
9
+
10
+ if (field === 'collection') {
11
+ initCollectionSearchInputs();
12
+ }
13
+ };
14
+
15
+ // hide all export_source
16
+ function hide(allSources) {
17
+ allSources.addClass('hidden');
18
+ allSources.find('#exporter_export_source').addClass('hidden').attr('type', 'hidden');
19
+ }
20
+
21
+ // unhide selected export_source
22
+ function unhideSelected(selectedSource) {
23
+ selectedSource.removeClass('hidden').removeAttr('type');
24
+ selectedSource.parent().removeClass('hidden').removeAttr('type');
25
+ };
26
+
27
+ // add the autocomplete javascript
28
+ function initCollectionSearchInputs() {
29
+ $('[data-autocomplete]').each((function() {
30
+ var elem = $(this)
31
+ initSelect2(elem, elem.data('autocompleteUrl'))
32
+ }))
33
+ }
34
+
35
+ function initSelect2(element, url) {
36
+ element.select2({
37
+ minimumInputLength: 2,
38
+ initSelection : (row, callback) => {
39
+ var data = {id: row.val(), text: row.val()};
40
+ callback(data);
41
+ },
42
+ ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
43
+ url: url,
44
+ dataType: 'json',
45
+ data: (term, page) => {
46
+ return {
47
+ q: term // search term
48
+ };
49
+ },
50
+ results: function(data, page) {
51
+ // parse the results into the format expected by Select2.
52
+ // since we are using custom formatting functions we do not need to alter remote JSON data
53
+ let results = data.map((obj) => {
54
+ return { id: obj.id, text: obj.label[0] };
55
+ })
56
+ return { results: results };
57
+ }
58
+ }
59
+ }).select2('data', null);
60
+ }
@@ -0,0 +1,166 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
3
+
4
+ function prepBulkrax(event) {
5
+ var refresh_button = $('.refresh-set-source')
6
+ var base_url = $('#importer_parser_fields_base_url')
7
+ var initial_base_url = base_url.val()
8
+ var file_path_value = $('#importer_parser_fields_import_file_path').val()
9
+ handleFileToggle(file_path_value)
10
+
11
+ // handle refreshing/loading of external sets via button click
12
+ $('body').on('click', '.refresh-set-source', function(e) {
13
+ e.preventDefault()
14
+
15
+ external_set_select = $("#importer_parser_fields_set")
16
+ handleSourceLoad(refresh_button, base_url, external_set_select)
17
+ })
18
+
19
+ // handle refreshing/loading of external sets via blur event for the base_url field
20
+ $('body').on('blur', '#importer_parser_fields_base_url', function(e) {
21
+ e.preventDefault()
22
+
23
+ // retrieve the latest base_url
24
+ base_url = $('#importer_parser_fields_base_url')
25
+
26
+ // ensure we don't make another query if the value is the same -- this can be forced by clicking the refresh button
27
+ if (initial_base_url != base_url.val()) {
28
+ external_set_select = $("#importer_parser_fields_set")
29
+ handleSourceLoad(refresh_button, base_url, external_set_select)
30
+ initial_base_url = base_url.val()
31
+ }
32
+ })
33
+
34
+ // hide and show correct parser fields depending on klass setting
35
+ $('body').on('change', '#importer_parser_klass', function(e) {
36
+ handleParserKlass()
37
+ })
38
+ handleParserKlass()
39
+
40
+ // observer for cloud files being added
41
+ var form = document.getElementById('new_importer');
42
+ if (form == null) {
43
+ var form = document.getElementsByClassName('edit_importer')[0];
44
+ }
45
+ // only setup the observer on the new and edit importer pages
46
+ if (form != null) {
47
+ var config = { childList: true, attributes: true };
48
+ var callback = function(mutationsList) {
49
+ for(var mutation of mutationsList) {
50
+ if (mutation.type == 'childList') {
51
+ browseButton = document.getElementById('browse');
52
+ var exp = /selected_files\[[0-9*]\]\[url\]/
53
+ for (var node of mutation.addedNodes) {
54
+ if (node.attributes != undefined) {
55
+ var name = node.attributes.name.value
56
+ if (exp.test(name)) {
57
+ browseButton.innerHTML = 'Cloud Files Added';
58
+ browseButton.style.backgroundColor = 'green';
59
+ browseButton.after(document.createElement("br"), node.value.toString())
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ };
66
+ var observer = new MutationObserver (callback);
67
+ observer.observe (form, config);
68
+ }
69
+ }
70
+
71
+ function handleFileToggle(file_path) {
72
+ if (file_path === undefined || file_path.length === 0) {
73
+ $('#file_path').hide()
74
+ $('#file_upload').hide()
75
+ $('#cloud').hide()
76
+ $('#file_path input').attr('required', null)
77
+ $('#file_upload input').attr('required', null)
78
+ } else {
79
+ $('#file_path').show()
80
+ $('#file_upload').hide()
81
+ $('#cloud').hide()
82
+ $('#file_path input').attr('required', 'required')
83
+ $('#file_upload input').attr('required', null)
84
+ $('#importer_parser_fields_file_style_specify_a_path_on_the_server').attr('checked', true)
85
+ }
86
+
87
+ $('#importer_parser_fields_file_style_upload_a_file').click(function(e){
88
+ $('#file_path').hide()
89
+ $('#file_upload').show()
90
+ $('#cloud').hide()
91
+ $('#file_path input').attr('required', null)
92
+ $('#file_upload input').attr('required', 'required')
93
+ })
94
+ $('#importer_parser_fields_file_style_specify_a_path_on_the_server').click(function(e){
95
+ $('#file_path').show()
96
+ $('#file_upload').hide()
97
+ $('#cloud').hide()
98
+ $('#file_path input').attr('required', 'required')
99
+ $('#file_upload input').attr('required', null)
100
+ })
101
+ $('#importer_parser_fields_file_style_add_cloud_file').click(function(e){
102
+ $('#file_path').hide()
103
+ $('#file_upload').hide()
104
+ $('#cloud').show()
105
+ $('#file_path input').attr('required', null)
106
+ $('#file_upload input').attr('required', null)
107
+ })
108
+ }
109
+
110
+ function handleParserKlass() {
111
+ <% Bulkrax.parsers.map{ |p| p[:partial]}.uniq.each do |partial| %>
112
+ if($('.<%= partial %>').length > 0) {
113
+ window.<%= partial %> = $('.<%= partial %>').detach()
114
+ }
115
+ <% end %>
116
+
117
+ var parser_klass = $("#importer_parser_klass option:selected")
118
+ if(parser_klass.length > 0 && parser_klass.data('partial') && parser_klass.data('partial').length > 0) {
119
+ $('.parser_fields').append(window[parser_klass.data('partial')])
120
+ }
121
+
122
+ var file_path_value = $('#importer_parser_fields_import_file_path').val()
123
+ handleFileToggle(file_path_value)
124
+ }
125
+
126
+ function handleSourceLoad(refresh_button, base_url, external_set_select) {
127
+ if (base_url.val() == "") { // ignore empty base_url value
128
+ return
129
+ }
130
+
131
+ var initial_button_text = refresh_button.html()
132
+
133
+ refresh_button.html('Refreshing...')
134
+ refresh_button.attr('disabled', true)
135
+
136
+ $.post('/importers/external_sets', {
137
+ base_url: base_url.val(),
138
+ }, function(res) {
139
+ if (!res.error) {
140
+ genExternalSetOptions(external_set_select, res.sets) // sets is [[name, spec]...]
141
+ } else {
142
+ setError(external_set_select, res.error)
143
+ }
144
+
145
+ refresh_button.html(initial_button_text)
146
+ refresh_button.attr('disabled', false)
147
+ })
148
+ }
149
+
150
+ function genExternalSetOptions(selector, sets) {
151
+ out = '<option value="">- Select One -</option>'
152
+
153
+ out += sets.map(function(set) {
154
+ return '<option value="'+set[1]+'">'+set[0]+'</option>'
155
+ })
156
+
157
+ selector.html(out)
158
+ selector.attr('disabled', false)
159
+ }
160
+
161
+ function setError(selector, error) {
162
+ selector.html('<option value="none">Error - Please enter Base URL and try again</option>')
163
+ selector.attr('disabled', true)
164
+ }
165
+
166
+ $(document).on({'ready': prepBulkrax, 'turbolinks:load': prepBulkrax})
@@ -0,0 +1,40 @@
1
+ .accordion-icon {
2
+ float: right;
3
+ margin: 0 auto;
4
+ font-size: 22px;
5
+ transform: rotate(45deg);
6
+ margin-top: -2px;
7
+ }
8
+
9
+ .accordion-container {
10
+ width: 100%;
11
+ padding: 0px;
12
+ margin: 10px 0px;
13
+ border-radius: 4px;
14
+ border: 1px solid #dedede;
15
+ }
16
+
17
+ .accordion-heading {
18
+ padding: 14px 15px;
19
+ background-color: #f5f5f5;
20
+ border-radius: 3px;
21
+ }
22
+
23
+ .accordion-title {
24
+ font-size: 14px;
25
+ font-weight: bold;
26
+ color: #4E4A42;
27
+ &:hover {
28
+ color: #4E4A42;
29
+ }
30
+ }
31
+
32
+ .accordion-collapse {
33
+ width: 100%;
34
+ padding: 0px;
35
+ }
36
+
37
+ .accordion-body {
38
+ padding: 14px;
39
+ width: 100%;
40
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,264 @@
1
+ #bulkrax-raw-toggle-1, #bulkrax-raw-toggle-2 {
2
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
3
+ font-size: 13px;
4
+ }
5
+
6
+ .CodeRay {
7
+ background-color: #FFF;
8
+ border: 1px solid #CCC;
9
+ font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
10
+ color: #000;
11
+ }
12
+
13
+ .CodeRay pre {
14
+ margin: auto 0px;
15
+ width: 100%;
16
+ }
17
+
18
+ span.CodeRay {
19
+ white-space: pre;
20
+ border: 0px;
21
+ padding: 2px
22
+ }
23
+
24
+ table.CodeRay {
25
+ border-collapse: collapse;
26
+ width: 100%;
27
+ padding: 2px;
28
+ }
29
+
30
+ table.CodeRay td {
31
+ padding: 1em 0.5em;
32
+ vertical-align: top;
33
+ }
34
+
35
+ .CodeRay .line-numbers, .CodeRay .no {
36
+ background-color: #ECECEC;
37
+ color: #AAA;
38
+ text-align: right;
39
+ }
40
+
41
+ .CodeRay .line-numbers a {
42
+ color: #AAA;
43
+ }
44
+
45
+ .CodeRay .line-numbers tt { font-weight: bold; }
46
+ .CodeRay .line-numbers .highlighted { color: red; }
47
+
48
+ .CodeRay .line {
49
+ display: block;
50
+ float: left;
51
+ width: 100%;
52
+ }
53
+
54
+ .CodeRay span.line-numbers { padding: 0px 4px; }
55
+ .CodeRay .code { width: 100%; }
56
+
57
+ ol.CodeRay { font-size: 10pt; }
58
+ ol.CodeRay li { white-space: pre; }
59
+
60
+ .CodeRay .code pre { overflow: auto; }
61
+
62
+ .CodeRay .annotation { color: #007; }
63
+ .CodeRay .attribute-name { color: #f08; }
64
+ .CodeRay .attribute-value { color: #700; }
65
+
66
+ .CodeRay .binary {
67
+ color: #509;
68
+ font-weight: bold;
69
+ }
70
+
71
+ .CodeRay .comment {
72
+ color: #998;
73
+ font-style: italic;
74
+ }
75
+
76
+ .CodeRay .char { color: #04D; }
77
+ .CodeRay .char .content { color: #04D; }
78
+ .CodeRay .char .delimiter { color: #039; }
79
+
80
+ .CodeRay .class {
81
+ color: #458;
82
+ font-weight: bold;
83
+ }
84
+
85
+ .CodeRay .complex {
86
+ color: #A08;
87
+ font-weight: bold;
88
+ }
89
+
90
+ .CodeRay .constant { color: teal; }
91
+ .CodeRay .color { color: #0A0; }
92
+ .CodeRay .class-variable { color: #369; }
93
+ .CodeRay .decorator { color: #B0B; }
94
+
95
+ .CodeRay .definition {
96
+ color: #099;
97
+ font-weight: bold;
98
+ }
99
+
100
+ .CodeRay .directive {
101
+ color: #088;
102
+ font-weight: bold;
103
+ }
104
+
105
+ .CodeRay .delimiter { color: black; }
106
+ .CodeRay .doc { color: #970; }
107
+ .CodeRay .doctype { color: #34b; }
108
+
109
+ .CodeRay .doc-string {
110
+ color: #D42;
111
+ font-weight: bold;
112
+ }
113
+
114
+ .CodeRay .escape {
115
+ color: #666;
116
+ font-weight: bold;
117
+ }
118
+
119
+ .CodeRay .entity {
120
+ color: #800;
121
+ font-weight: bold;
122
+ }
123
+
124
+ .CodeRay .error {
125
+ color: #F00;
126
+ background-color: #FAA;
127
+ }
128
+
129
+ .CodeRay .exception {
130
+ color: #C00;
131
+ font-weight: bold;
132
+ }
133
+
134
+ .CodeRay .filename { color: #099; }
135
+
136
+ .CodeRay .function {
137
+ color: #900;
138
+ font-weight: bold;
139
+ }
140
+
141
+ .CodeRay .global-variable {
142
+ color: teal;
143
+ font-weight: bold;
144
+ }
145
+
146
+ .CodeRay .hex {
147
+ color: #058;
148
+ font-weight: bold;
149
+ }
150
+
151
+ .CodeRay .integer { color: #099; }
152
+
153
+ .CodeRay .include {
154
+ color: #B44;
155
+ font-weight: bold;
156
+ }
157
+
158
+ .CodeRay .inline { color: #000; }
159
+ .CodeRay .inline .inline { background: #ccc; }
160
+ .CodeRay .inline .inline .inline { background: #bbb; }
161
+ .CodeRay .inline .inline-delimiter { color: #D14; }
162
+ .CodeRay .inline-delimiter { color: #D14; }
163
+ .CodeRay .important { color: #f00; }
164
+
165
+ .CodeRay .interpreted {
166
+ color: #B2B;
167
+ font-weight: bold;
168
+ }
169
+
170
+ .CodeRay .instance-variable { color: teal; }
171
+
172
+ .CodeRay .label {
173
+ color: #970;
174
+ font-weight: bold;
175
+ }
176
+
177
+ .CodeRay .local-variable { color: #963; }
178
+
179
+ .CodeRay .octal {
180
+ color: #40E;
181
+ font-weight: bold;
182
+ }
183
+
184
+ .CodeRay .predefined-constant { font-weight: bold; }
185
+
186
+ .CodeRay .predefined {
187
+ color: #369;
188
+ font-weight: bold;
189
+ }
190
+ .CodeRay .preprocessor { color: #579; }
191
+
192
+ .CodeRay .pseudo-class {
193
+ color: #00C;
194
+ font-weight: bold;
195
+ }
196
+ .CodeRay .predefined-type { color: #074; font-weight: bold; }
197
+ .CodeRay .reserved, .keyword { color: #000; font-weight: bold; }
198
+
199
+ .CodeRay .key { color: #808; }
200
+ .CodeRay .key .delimiter { color: #606; }
201
+ .CodeRay .key .char { color: #80f; }
202
+ .CodeRay .value { color: #088; }
203
+
204
+ .CodeRay .regexp { background-color: #fff0ff; }
205
+ .CodeRay .regexp .content { color: #808; }
206
+ .CodeRay .regexp .delimiter { color: #404; }
207
+ .CodeRay .regexp .modifier { color: #C2C; }
208
+
209
+ .CodeRay .regexp .function {
210
+ color: #404;
211
+ font-weight: bold;
212
+ }
213
+
214
+ .CodeRay .string { color: #D20; }
215
+ .CodeRay .string .string .string { background-color: #ffd0d0; }
216
+ .CodeRay .string .content { color: #D14; }
217
+ .CodeRay .string .char { color: #D14; }
218
+ .CodeRay .string .delimiter { color: #D14; }
219
+
220
+ .CodeRay .shell { color: #D14; }
221
+ .CodeRay .shell .delimiter { color: #D14; }
222
+
223
+ .CodeRay .symbol { color: #990073; }
224
+ .CodeRay .symbol .content { color: #A60; }
225
+ .CodeRay .symbol .delimiter { color: #630; }
226
+
227
+ .CodeRay .tag { color: #070; }
228
+
229
+ .CodeRay .tag-special {
230
+ color: #D70;
231
+ font-weight: bold;
232
+ }
233
+
234
+ .CodeRay .type {
235
+ color: #339;
236
+ font-weight: bold;
237
+ }
238
+
239
+ .CodeRay .variable { color: #036; }
240
+ .CodeRay .insert { background: #afa; }
241
+ .CodeRay .delete { background: #faa; }
242
+
243
+ .CodeRay .change {
244
+ color: #aaf;
245
+ background: #007;
246
+ }
247
+
248
+ .CodeRay .head {
249
+ color: #f8f;
250
+ background: #505;
251
+ }
252
+
253
+ .CodeRay .insert .insert {
254
+ color: #080;
255
+ font-weight: bold;
256
+ }
257
+
258
+ .CodeRay .delete .delete {
259
+ color: #800;
260
+ font-weight: bold;
261
+ }
262
+
263
+ .CodeRay .change .change { color: #66f; }
264
+ .CodeRay .head .head { color: #f4f; }