scriptorium 0.0.3 → 0.7.2
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/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/myuserdoc/userdoc-toc.txt +88 -0
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,149 @@
|
|
1
|
+
class Scriptorium::Widget::FeaturedPosts < Scriptorium::Widget::ListWidget
|
2
|
+
include Scriptorium::Contract
|
3
|
+
|
4
|
+
Title = "Featured Posts"
|
5
|
+
|
6
|
+
# Invariants
|
7
|
+
def define_invariants
|
8
|
+
invariant { @lines.is_a?(Array) }
|
9
|
+
invariant { Title.is_a?(String) && !Title.empty? }
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(repo, view)
|
13
|
+
assume { repo.is_a?(Scriptorium::Repo) }
|
14
|
+
assume { view.is_a?(Scriptorium::View) }
|
15
|
+
|
16
|
+
super(repo, view)
|
17
|
+
@lines = @data
|
18
|
+
|
19
|
+
define_invariants
|
20
|
+
verify { @lines == @data }
|
21
|
+
check_invariants
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_config
|
25
|
+
check_invariants
|
26
|
+
# No configuration needed for this widget
|
27
|
+
check_invariants
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate
|
31
|
+
check_invariants
|
32
|
+
assume { @view.is_a?(Scriptorium::View) }
|
33
|
+
|
34
|
+
write_main
|
35
|
+
write_card
|
36
|
+
result = true
|
37
|
+
|
38
|
+
verify { result == true }
|
39
|
+
check_invariants
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
def widget_title
|
44
|
+
check_invariants
|
45
|
+
result = Title
|
46
|
+
verify { result.is_a?(String) && !result.empty? }
|
47
|
+
check_invariants
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
def card
|
52
|
+
check_invariants
|
53
|
+
assume { @view.is_a?(Scriptorium::View) }
|
54
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
55
|
+
|
56
|
+
file = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
57
|
+
result = read_file(file)
|
58
|
+
|
59
|
+
verify { result.is_a?(String) }
|
60
|
+
check_invariants
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def write_main
|
65
|
+
check_invariants
|
66
|
+
# Nothing in this case
|
67
|
+
check_invariants
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_featured_line(line)
|
71
|
+
check_invariants
|
72
|
+
assume { line.is_a?(String) }
|
73
|
+
|
74
|
+
# Parse line in format: <id> <title>
|
75
|
+
# Title is optional, so we need to handle both cases
|
76
|
+
parts = line.strip.split(/\s+/, 2)
|
77
|
+
if parts.length >= 2
|
78
|
+
result = [parts[0], parts[1]]
|
79
|
+
else
|
80
|
+
result = [parts[0], nil]
|
81
|
+
end
|
82
|
+
|
83
|
+
verify { result.is_a?(Array) && result.length == 2 }
|
84
|
+
check_invariants
|
85
|
+
result
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_post_title(post_id)
|
89
|
+
check_invariants
|
90
|
+
assume { post_id.is_a?(String) && !post_id.empty? }
|
91
|
+
assume { @repo.is_a?(Scriptorium::Repo) }
|
92
|
+
|
93
|
+
# Get the actual post title from metadata
|
94
|
+
post = Scriptorium::Post.new(@repo, post_id)
|
95
|
+
|
96
|
+
# Check if the post actually exists by looking for the meta file
|
97
|
+
if File.exist?(post.meta_file)
|
98
|
+
result = post.title || "Untitled Post"
|
99
|
+
else
|
100
|
+
result = "Error: Post #{post_id} not found"
|
101
|
+
end
|
102
|
+
rescue => e
|
103
|
+
# If post can't be created (invalid ID, etc.), return error message
|
104
|
+
result = "Error: Post #{post_id} not found"
|
105
|
+
ensure
|
106
|
+
verify { result.is_a?(String) && !result.empty? }
|
107
|
+
check_invariants
|
108
|
+
result
|
109
|
+
end
|
110
|
+
|
111
|
+
def featured_post_item(post_id, list_title = nil)
|
112
|
+
check_invariants
|
113
|
+
assume { post_id.is_a?(String) && !post_id.empty? }
|
114
|
+
assume { list_title.nil? || list_title.is_a?(String) }
|
115
|
+
|
116
|
+
# Use actual post title from metadata, show error if post doesn't exist
|
117
|
+
display_title = get_post_title(post_id)
|
118
|
+
|
119
|
+
# Create link to the post (or error message)
|
120
|
+
anchor = %[<a href="javascript:void(0)" onclick="load_main('posts/#{post_id}.html')" style="text-decoration: none;">#{display_title}</a>]
|
121
|
+
result = %[<li class="list-group-item">#{anchor}</li>]
|
122
|
+
|
123
|
+
verify { result.is_a?(String) && result.include?("list-group-item") }
|
124
|
+
check_invariants
|
125
|
+
result
|
126
|
+
end
|
127
|
+
|
128
|
+
def write_card
|
129
|
+
check_invariants
|
130
|
+
assume { @view.is_a?(Scriptorium::View) }
|
131
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
132
|
+
assume { @data.is_a?(Array) }
|
133
|
+
|
134
|
+
tag = @name
|
135
|
+
cardout = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
136
|
+
card_title = Title
|
137
|
+
content = ""
|
138
|
+
|
139
|
+
@data.each do |line|
|
140
|
+
next if line.strip.empty?
|
141
|
+
|
142
|
+
post_id, list_title = parse_featured_line(line)
|
143
|
+
content << featured_post_item(post_id, list_title)
|
144
|
+
end
|
145
|
+
|
146
|
+
write_file(cardout, html_card(card_title, tag, content))
|
147
|
+
check_invariants
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
class Scriptorium::Widget::Links < Scriptorium::Widget::ListWidget
|
2
|
+
include Scriptorium::Contract
|
3
|
+
|
4
|
+
Title = "External links"
|
5
|
+
|
6
|
+
# Invariants
|
7
|
+
def define_invariants
|
8
|
+
invariant { @lines.is_a?(Array) }
|
9
|
+
invariant { Title.is_a?(String) && !Title.empty? }
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(repo, view)
|
13
|
+
assume { repo.is_a?(Scriptorium::Repo) }
|
14
|
+
assume { view.is_a?(Scriptorium::View) }
|
15
|
+
|
16
|
+
super(repo, view)
|
17
|
+
@lines = @data
|
18
|
+
|
19
|
+
define_invariants
|
20
|
+
verify { @lines == @data }
|
21
|
+
check_invariants
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_list
|
25
|
+
check_invariants
|
26
|
+
assume { @lines.is_a?(Array) }
|
27
|
+
|
28
|
+
result = @lines.map { |line| line.chomp.split(/, */, 2) }
|
29
|
+
|
30
|
+
verify { result.is_a?(Array) }
|
31
|
+
check_invariants
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_config
|
36
|
+
check_invariants
|
37
|
+
# No configuration needed for this widget
|
38
|
+
check_invariants
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate
|
42
|
+
check_invariants
|
43
|
+
assume { @view.is_a?(Scriptorium::View) }
|
44
|
+
|
45
|
+
write_main
|
46
|
+
write_card
|
47
|
+
result = true
|
48
|
+
|
49
|
+
verify { result == true }
|
50
|
+
check_invariants
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def widget_title
|
55
|
+
check_invariants
|
56
|
+
result = Title
|
57
|
+
verify { result.is_a?(String) && !result.empty? }
|
58
|
+
check_invariants
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
def card
|
63
|
+
check_invariants
|
64
|
+
assume { @view.is_a?(Scriptorium::View) }
|
65
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
66
|
+
|
67
|
+
file = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
68
|
+
result = read_file(file)
|
69
|
+
|
70
|
+
verify { result.is_a?(String) }
|
71
|
+
check_invariants
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
def write_main
|
76
|
+
check_invariants
|
77
|
+
# Nothing in this case
|
78
|
+
check_invariants
|
79
|
+
end
|
80
|
+
|
81
|
+
def link_item(url, title)
|
82
|
+
check_invariants
|
83
|
+
assume { url.is_a?(String) && !url.empty? }
|
84
|
+
assume { title.is_a?(String) && !title.empty? }
|
85
|
+
|
86
|
+
anchor = %[<a href="#{url}" target="_blank" style="text-decoration: none;">#{title}</a>]
|
87
|
+
result = %[<li class="list-group-item">#{anchor}</li>]
|
88
|
+
|
89
|
+
verify { result.is_a?(String) && result.include?("list-group-item") }
|
90
|
+
check_invariants
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
def write_card
|
95
|
+
check_invariants
|
96
|
+
assume { @view.is_a?(Scriptorium::View) }
|
97
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
98
|
+
assume { @data.is_a?(Array) }
|
99
|
+
|
100
|
+
tag = @name
|
101
|
+
cardout = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
102
|
+
# url = "../widgets/#@name/#@name-card.html"
|
103
|
+
card_title = Title
|
104
|
+
content = ""
|
105
|
+
@data.each do |line|
|
106
|
+
url2, title = line.chomp.split(",")
|
107
|
+
content << link_item(url2, title)
|
108
|
+
end
|
109
|
+
write_file(cardout, html_card(card_title, tag, content))
|
110
|
+
check_invariants
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
class Scriptorium::Widget::Pages < Scriptorium::Widget::ListWidget
|
2
|
+
include Scriptorium::Contract
|
3
|
+
|
4
|
+
Title = "Pages"
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
# Invariants
|
8
|
+
def define_invariants
|
9
|
+
invariant { @pages_dir.is_a?(String) && !@pages_dir.empty? }
|
10
|
+
invariant { @data.is_a?(Array) }
|
11
|
+
invariant { Title.is_a?(String) && !Title.empty? }
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(repo, view)
|
15
|
+
assume { repo.is_a?(Scriptorium::Repo) }
|
16
|
+
assume { view.is_a?(Scriptorium::View) }
|
17
|
+
|
18
|
+
super(repo, view)
|
19
|
+
@pages_dir = "#{@view.dir}/pages"
|
20
|
+
|
21
|
+
define_invariants
|
22
|
+
verify { @pages_dir.include?("pages") }
|
23
|
+
check_invariants
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_config
|
27
|
+
check_invariants
|
28
|
+
# No configuration needed for this widget
|
29
|
+
check_invariants
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate
|
33
|
+
check_invariants
|
34
|
+
assume { @view.is_a?(Scriptorium::View) }
|
35
|
+
|
36
|
+
write_main
|
37
|
+
write_card
|
38
|
+
result = true
|
39
|
+
|
40
|
+
verify { result == true }
|
41
|
+
check_invariants
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def widget_title
|
46
|
+
check_invariants
|
47
|
+
result = Title
|
48
|
+
verify { result.is_a?(String) && !result.empty? }
|
49
|
+
check_invariants
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
def card
|
54
|
+
check_invariants
|
55
|
+
assume { @view.is_a?(Scriptorium::View) }
|
56
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
57
|
+
|
58
|
+
file = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
59
|
+
result = read_file(file)
|
60
|
+
|
61
|
+
verify { result.is_a?(String) }
|
62
|
+
check_invariants
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def write_main
|
67
|
+
check_invariants
|
68
|
+
# Nothing in this case
|
69
|
+
check_invariants
|
70
|
+
end
|
71
|
+
|
72
|
+
def extract_title_from_html(html_content)
|
73
|
+
check_invariants
|
74
|
+
assume { html_content.is_a?(String) }
|
75
|
+
|
76
|
+
# Try to extract title from <title> tag first
|
77
|
+
if match = html_content.match(/<title[^>]*>(.*?)<\/title>/i)
|
78
|
+
result = match[1].strip
|
79
|
+
elsif match = html_content.match(/<h1[^>]*>(.*?)<\/h1>/i)
|
80
|
+
# Fall back to first <h1> tag
|
81
|
+
result = match[1].strip
|
82
|
+
else
|
83
|
+
# Last resort: use filename
|
84
|
+
result = "Untitled"
|
85
|
+
end
|
86
|
+
|
87
|
+
verify { result.is_a?(String) && !result.empty? }
|
88
|
+
check_invariants
|
89
|
+
result
|
90
|
+
end
|
91
|
+
|
92
|
+
def page_item(filename, title)
|
93
|
+
check_invariants
|
94
|
+
assume { filename.is_a?(String) && !filename.empty? }
|
95
|
+
assume { title.is_a?(String) && !title.empty? }
|
96
|
+
|
97
|
+
anchor = %[<a href="javascript:void(0)" onclick="load_main('pages/#{filename}.html')" style="text-decoration: none;">#{title}</a>]
|
98
|
+
result = %[<li class="list-group-item">#{anchor}</li>]
|
99
|
+
|
100
|
+
verify { result.is_a?(String) && result.include?("list-group-item") }
|
101
|
+
check_invariants
|
102
|
+
result
|
103
|
+
end
|
104
|
+
|
105
|
+
def write_card
|
106
|
+
check_invariants
|
107
|
+
assume { @view.is_a?(Scriptorium::View) }
|
108
|
+
assume { @name.is_a?(String) && !@name.empty? }
|
109
|
+
assume { @data.is_a?(Array) }
|
110
|
+
assume { @pages_dir.is_a?(String) && !@pages_dir.empty? }
|
111
|
+
|
112
|
+
tag = @name
|
113
|
+
cardout = "#{@view.dir}/widgets/#@name/#@name-card.html"
|
114
|
+
card_title = Title
|
115
|
+
content = ""
|
116
|
+
|
117
|
+
@data.each do |filename|
|
118
|
+
html_file = "#{@pages_dir}/#{filename}.html"
|
119
|
+
|
120
|
+
if File.exist?(html_file)
|
121
|
+
html_content = read_file(html_file)
|
122
|
+
title = extract_title_from_html(html_content)
|
123
|
+
content << page_item(filename, title)
|
124
|
+
else
|
125
|
+
# Page doesn't exist, skip it
|
126
|
+
next
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
write_file(cardout, html_card(card_title, tag, content))
|
131
|
+
check_invariants
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
class Scriptorium::Widget
|
2
|
+
include Scriptorium::Helpers
|
3
|
+
include Scriptorium::Contract
|
4
|
+
attr_reader :repo, :view, :config, :name, :path
|
5
|
+
|
6
|
+
# Invariants
|
7
|
+
def define_invariants
|
8
|
+
invariant { @repo.is_a?(Scriptorium::Repo) }
|
9
|
+
invariant { @view.is_a?(Scriptorium::View) }
|
10
|
+
invariant { @name.is_a?(String) && !@name.empty? }
|
11
|
+
invariant { @path.is_a?(String) && !@path.empty? }
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(repo, view)
|
15
|
+
assume { repo.is_a?(Scriptorium::Repo) }
|
16
|
+
assume { view.is_a?(Scriptorium::View) }
|
17
|
+
|
18
|
+
@repo = repo
|
19
|
+
@view = view
|
20
|
+
@config = load_config
|
21
|
+
@name = self.class.to_s.split("::").last.downcase
|
22
|
+
@path = "#{@view.dir}/widgets/#@name"
|
23
|
+
|
24
|
+
define_invariants
|
25
|
+
verify { @repo == repo }
|
26
|
+
verify { @view == view }
|
27
|
+
check_invariants
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate
|
31
|
+
raise NotImplementedError, "Subclasses must implement the 'generate' method"
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_config
|
35
|
+
raise NotImplementedError, "Subclasses must implement 'load_config'"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Common HTML body wrapper for widgets
|
39
|
+
def html_body(css = nil)
|
40
|
+
check_invariants
|
41
|
+
assume { css.nil? || css.is_a?(String) }
|
42
|
+
|
43
|
+
result = "<html>" +
|
44
|
+
(css ? "<head><style>#{css}</style></head>" : "") +
|
45
|
+
"<body>" + yield + "</body></html>"
|
46
|
+
|
47
|
+
verify { result.is_a?(String) && result.include?("<html>") }
|
48
|
+
check_invariants
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
# Common HTML card structure for widgets like Links
|
53
|
+
def html_card(card_title = "Widget Card", tag = "widget", content)
|
54
|
+
check_invariants
|
55
|
+
assume { card_title.is_a?(String) }
|
56
|
+
assume { tag.is_a?(String) }
|
57
|
+
assume { content.is_a?(String) }
|
58
|
+
|
59
|
+
result = <<~EOS
|
60
|
+
<div class="card mb-3">
|
61
|
+
<div class="card-body">
|
62
|
+
<h5 class="card-title">
|
63
|
+
<button type="button" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="##{tag}">+</button>
|
64
|
+
<a href="javascript:void(0)" onclick="javascript:load_main('#{tag}-main.html')" style="text-decoration: none; color: black">#{card_title}</a>
|
65
|
+
</h5>
|
66
|
+
<div class="collapse" id="#{tag}">
|
67
|
+
#{content}
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
EOS
|
72
|
+
|
73
|
+
verify { result.is_a?(String) && result.include?("card") }
|
74
|
+
check_invariants
|
75
|
+
result
|
76
|
+
end
|
77
|
+
|
78
|
+
# A generic container for widget content (for those that don't use cards)
|
79
|
+
def html_container(content)
|
80
|
+
check_invariants
|
81
|
+
assume { content.is_a?(String) }
|
82
|
+
|
83
|
+
result = <<~HTML
|
84
|
+
<div class="widget-container">
|
85
|
+
#{content}
|
86
|
+
</div>
|
87
|
+
HTML
|
88
|
+
|
89
|
+
verify { result.is_a?(String) && result.include?("widget-container") }
|
90
|
+
check_invariants
|
91
|
+
result
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
####
|
97
|
+
|
98
|
+
|
99
|
+
class Scriptorium::Widget::ListWidget < Scriptorium::Widget
|
100
|
+
include Scriptorium::Contract
|
101
|
+
|
102
|
+
# Invariants
|
103
|
+
def define_invariants
|
104
|
+
invariant { @list.is_a?(String) && !@list.empty? }
|
105
|
+
invariant { @data.is_a?(Array) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize(repo, view)
|
109
|
+
assume { repo.is_a?(Scriptorium::Repo) }
|
110
|
+
assume { view.is_a?(Scriptorium::View) }
|
111
|
+
|
112
|
+
super(repo, view)
|
113
|
+
@list = "#{@path}/list.txt"
|
114
|
+
@data = load_data
|
115
|
+
|
116
|
+
define_invariants
|
117
|
+
verify { @list.include?("list.txt") }
|
118
|
+
verify { @data.is_a?(Array) }
|
119
|
+
check_invariants
|
120
|
+
end
|
121
|
+
|
122
|
+
# Method to load the list data from the list.txt file
|
123
|
+
def load_data
|
124
|
+
check_invariants
|
125
|
+
assume { @list.is_a?(String) && !@list.empty? }
|
126
|
+
|
127
|
+
result = read_file(@list, lines: true, chomp: true).map(&:strip)
|
128
|
+
|
129
|
+
verify { result.is_a?(Array) }
|
130
|
+
check_invariants
|
131
|
+
result
|
132
|
+
end
|
133
|
+
end
|
data/lib/scriptorium.rb
CHANGED
@@ -1,42 +1,46 @@
|
|
1
|
-
|
1
|
+
require 'livetext'
|
2
|
+
require 'find'
|
3
|
+
require 'htmlbeautifier'
|
4
|
+
require 'pp'
|
5
|
+
require 'digest'
|
2
6
|
|
3
|
-
require_relative "
|
7
|
+
require_relative "skeleton"
|
8
|
+
require_relative "scriptorium/version"
|
9
|
+
require_relative "scriptorium/contract"
|
10
|
+
require_relative "scriptorium/repo"
|
11
|
+
require_relative "scriptorium/post"
|
12
|
+
require_relative "scriptorium/theme"
|
13
|
+
require_relative "scriptorium/view"
|
4
14
|
require_relative "scriptorium/exceptions"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
15
|
+
require_relative "scriptorium/helpers"
|
16
|
+
require_relative "scriptorium/standard_files"
|
17
|
+
require_relative "scriptorium/banner_svg"
|
18
|
+
require_relative "scriptorium/reddit"
|
19
|
+
require_relative "scriptorium/widgets/widget"
|
20
|
+
require_relative "scriptorium/widgets/links"
|
21
|
+
require_relative "scriptorium/widgets/pages"
|
22
|
+
require_relative "scriptorium/widgets/featured_posts"
|
23
|
+
require_relative "scriptorium/api"
|
24
|
+
|
25
|
+
# Main Scriptorium class that provides backward compatibility
|
10
26
|
class Scriptorium
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
include Exceptions
|
15
|
-
include Engine
|
16
|
-
|
17
|
-
# Class instance vars...
|
18
|
-
@testing = $testing # good/bad idea?
|
19
|
-
@blog = nil
|
20
|
-
|
21
|
-
class << self
|
22
|
-
attr_accessor :testing
|
23
|
-
alias blog instance
|
27
|
+
def initialize(testmode: false)
|
28
|
+
@api = Scriptorium::API.new(testmode: testmode)
|
24
29
|
end
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def initialize
|
31
|
-
@testing = self.class.testing
|
32
|
-
@home = ENV['HOME']
|
33
|
-
if @testing
|
34
|
-
@name = "TEST-ONLY BLOG REPO"
|
35
|
-
@dir = "#@home/test-scriptorium"
|
30
|
+
|
31
|
+
# Delegate all the main operations to the API
|
32
|
+
def method_missing(method, *args, **kwargs, &block)
|
33
|
+
if @api.respond_to?(method)
|
34
|
+
@api.send(method, *args, **kwargs, &block)
|
36
35
|
else
|
37
|
-
|
38
|
-
@dir = "#@home/Scriptorium"
|
36
|
+
super
|
39
37
|
end
|
40
38
|
end
|
41
|
-
|
39
|
+
|
40
|
+
def respond_to_missing?(method, include_private = false)
|
41
|
+
@api.respond_to?(method) || super
|
42
|
+
end
|
43
|
+
|
44
|
+
# Keep the API accessible for advanced users
|
45
|
+
attr_reader :api
|
42
46
|
end
|
data/lib/skeleton.rb
CHANGED
data/scriptorium.gemspec
CHANGED
@@ -21,27 +21,39 @@ spec = Gem::Specification.new do |s|
|
|
21
21
|
s.authors = ["Hal Fulton"]
|
22
22
|
s.email = 'rubyhacker@gmail.com'
|
23
23
|
s.executables << "sblog"
|
24
|
+
s.executables << "scriptorium"
|
24
25
|
|
25
26
|
s.add_runtime_dependency 'livetext', '~> 0.9', '>= 0.9.41'
|
26
27
|
s.add_runtime_dependency 'rubytext', '~> 0.1', '>= 0.1.26'
|
27
28
|
s.add_runtime_dependency 'rouge', '~> 3.25', '>= 3.25.0'
|
29
|
+
s.add_runtime_dependency 'sinatra', '~> 3.0', '>= 3.0.0'
|
30
|
+
s.add_runtime_dependency 'redd', '~> 0.8.8'
|
31
|
+
s.add_runtime_dependency 'x', '~> 1.0'
|
32
|
+
s.add_runtime_dependency 'htmlbeautifier', '~> 1.4', '>= 1.4.0'
|
33
|
+
s.add_runtime_dependency 'clipboard', '~> 1.3', '>= 1.3.6'
|
28
34
|
|
29
35
|
s.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.0'
|
30
36
|
|
31
37
|
# Files...
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
Find.find("doc").to_a
|
39
|
+
# Core library files
|
40
|
+
main = Find.find("lib").to_a +
|
41
|
+
Find.find("doc").to_a +
|
42
|
+
Find.find("assets").to_a
|
43
|
+
|
44
|
+
# UI-specific files
|
45
|
+
ui_files = Find.find("ui").to_a
|
46
|
+
|
47
|
+
# Test files
|
36
48
|
test = Find.find("test").to_a
|
37
49
|
|
38
50
|
misc = %w[./README.lt3 ./README.md ./scriptorium.gemspec]
|
39
51
|
|
40
|
-
s.files = main + misc + test
|
52
|
+
s.files = main + ui_files + misc + test
|
41
53
|
s.homepage = 'https://github.com/Hal9000/scriptorium'
|
42
54
|
s.license = "Ruby"
|
43
55
|
s.post_install_message =
|
44
|
-
"\n Success! Run 'sblog'
|
56
|
+
"\n Success! Run command 'sblog help' to get started.\n "
|
45
57
|
end
|
46
58
|
|
47
59
|
spec
|