scriptorium 0.6.1 → 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/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
- 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/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/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
- 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_integration.md +2 -2
- data/doc/user.lt3 +0 -3
- data/lib/scriptorium/api.rb +1811 -78
- data/lib/scriptorium/banner_svg.rb +55 -68
- data/lib/scriptorium/contract.rb +3 -2
- data/lib/scriptorium/exceptions.rb +133 -102
- data/lib/scriptorium/helpers.rb +282 -82
- data/lib/scriptorium/post.rb +81 -17
- data/lib/scriptorium/reddit.rb +1 -1
- data/lib/scriptorium/repo.rb +478 -164
- data/lib/scriptorium/standard_files.rb +30 -396
- 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_template.txt +17 -0
- data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -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/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
- data/lib/scriptorium/theme.rb +83 -70
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +194 -149
- data/lib/scriptorium.rb +24 -1
- data/lib/skeleton.rb +4 -1
- data/scriptorium.gemspec +2 -1
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +40 -0
- data/test/banner_svg/unit.rb +267 -35
- data/test/config/deployment.txt +5 -0
- data/test/integration/integration_test.rb +7 -7
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +453 -182
- data/test/manual/banner-tests/test01.html +82 -18
- data/test/manual/banner-tests/test02.html +82 -18
- data/test/manual/banner-tests/test03.html +82 -18
- data/test/manual/banner-tests/test04.html +89 -25
- data/test/manual/banner-tests/test05.html +89 -25
- data/test/manual/banner-tests/test06.html +89 -25
- data/test/manual/banner-tests/test07.html +89 -25
- data/test/manual/banner-tests/test08.html +82 -18
- data/test/manual/banner-tests/test09.html +82 -18
- data/test/manual/banner-tests/test10.html +82 -18
- data/test/manual/banner-tests/test11.html +82 -18
- data/test/manual/banner-tests/test12.html +82 -18
- data/test/manual/banner-tests/test13.html +82 -18
- data/test/manual/banner-tests/test14.html +82 -18
- data/test/manual/banner-tests/test15.html +82 -18
- data/test/manual/banner-tests/test16.html +82 -18
- data/test/manual/banner-tests/test17.html +82 -18
- data/test/manual/banner-tests/test18.html +90 -26
- data/test/manual/banner-tests/test19.html +90 -26
- data/test/manual/banner-tests/test20.html +90 -26
- data/test/manual/banner-tests/test21.html +90 -26
- data/test/manual/banner-tests/test22.html +90 -26
- data/test/manual/banner-tests/test23.html +90 -26
- data/test/manual/banner-tests/test24.html +90 -26
- data/test/manual/banner-tests/test25.html +89 -25
- data/test/manual/banner_environment.rb +15 -2
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/test_banner_features.rb +14 -14
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_syntax_highlighting.rb +60 -40
- data/test/support/preview_utils.rb +88 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +10 -0
- data/test/tui_editor_integration_test.rb +15 -15
- data/test/tui_integration_test.rb +687 -441
- data/test/unit/api.rb +757 -37
- data/test/unit/asset_management.rb +195 -221
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/contract_test.rb +1 -23
- data/test/unit/core.rb +415 -61
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +312 -21
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +36 -42
- data/test/unit/livetext_basic.rb +23 -35
- data/test/unit/livetext_compatibility.rb +7 -14
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
- data/test/unit/post.rb +91 -26
- 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 +8 -6
- data/test/unit/repo.rb +75 -54
- data/test/unit/social_test.rb +41 -44
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +79 -12
- data/test/unit/widgets.rb +8 -8
- 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/ui/tui/bin/scriptorium +885 -415
- data/ui/web/app/app.rb +1398 -176
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +16 -16
- data/ui/web/app/views/advanced_config.erb +8 -2
- data/ui/web/app/views/asset_management.erb +56 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/dashboard.erb +64 -72
- data/ui/web/app/views/deploy_config.erb +3 -0
- data/ui/web/app/views/edit_pages.erb +170 -2
- data/ui/web/app/views/edit_post.erb +130 -9
- 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/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +666 -25
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +35 -24
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -5
- metadata +190 -116
- data/assets/back-icon.png +0 -0
- data/assets/icons/facebook.svg +0 -1
- data/assets/icons/github.svg +0 -1
- data/assets/icons/instagram.svg +0 -1
- data/assets/icons/reddit.svg +0 -1
- data/assets/icons/x.svg +0 -1
- data/assets/icons/youtube.svg +0 -1
- data/bin/scriptorium +0 -1511
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
- data/lib/scriptorium/syntax_highlighter.rb +0 -234
- data/test/manual/deploy_symlink_demo.rb +0 -142
- data/test/manual/symlink_demo.rb +0 -117
- data/test/manual/test2.rb +0 -12
- data/test/manual/test_banner_from_file.rb +0 -150
- data/test/manual/test_banner_in_header.rb +0 -35
- data/test/manual/test_code_highlighting.rb +0 -68
- data/test/manual/test_complex_header.rb +0 -74
- data/test/manual/test_empty_header.rb +0 -32
- data/test/manual/test_radial_custom.rb +0 -58
- data/test/manual/test_radial_large_radius.rb +0 -52
- data/test/manual/test_svg_debug.rb +0 -47
- data/test/pages-demo/config/currentview.txt +0 -1
- data/test/pages-demo/views/demo/config/common.js +0 -57
- data/test/pages-demo/views/demo/config/footer.txt +0 -1
- data/test/pages-demo/views/demo/config/global-head.txt +0 -8
- data/test/pages-demo/views/demo/config/header.txt +0 -1
- data/test/pages-demo/views/demo/config/layout.txt +0 -1
- data/test/pages-demo/views/demo/config/left.txt +0 -1
- data/test/pages-demo/views/demo/config/main.txt +0 -1
- data/test/pages-demo/views/demo/config/right.txt +0 -1
- data/test/pages-demo/views/demo/config.txt +0 -3
- data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
- data/test/pages-demo/views/demo/output/panes/header.html +0 -1
- data/test/pages-demo/views/demo/output/panes/left.html +0 -1
- data/test/pages-demo/views/demo/output/panes/main.html +0 -1
- data/test/pages-demo/views/demo/output/panes/right.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
- data/ui/web/tmp/web_server.pid +0 -1
- /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
- /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
- /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
- /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
- /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
- /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
- /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
- /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
@@ -4,16 +4,24 @@ manual_setup
|
|
4
4
|
|
5
5
|
@repo.create_view("testview", "Test View", "A test view for manual inspection")
|
6
6
|
|
7
|
-
#
|
7
|
+
# Ensure Highlight.js is enabled via global-head.txt
|
8
8
|
global_head_file = "test/scriptorium-TEST/views/testview/config/global-head.txt"
|
9
|
-
File.
|
10
|
-
|
11
|
-
|
9
|
+
head_contents = File.exist?(global_head_file) ? File.read(global_head_file) : ""
|
10
|
+
add_lines = []
|
11
|
+
add_lines << "highlight # Enable Highlight.js assets" unless head_contents.include?("\nhighlight")
|
12
|
+
add_lines << "highlight_custom # Optional Highlight.js CSS overrides" unless head_contents.include?("\nhighlight_custom")
|
13
|
+
unless add_lines.empty?
|
14
|
+
File.open(global_head_file, "a") { |f| add_lines.each { |ln| f.puts ln } }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Post with comprehensive syntax highlighting tests
|
12
18
|
draft_body = <<~'BODY'
|
13
|
-
.blurb
|
14
|
-
|
19
|
+
.blurb
|
20
|
+
Testing Highlight.js syntax highlighting with multiple languages.
|
21
|
+
.end
|
22
|
+
This post tests the integrated syntax highlighters with Ruby, Elixir, JavaScript, and plain text.
|
15
23
|
|
16
|
-
## Ruby Code Example
|
24
|
+
## Ruby Code Example (Rouge)
|
17
25
|
|
18
26
|
.code ruby
|
19
27
|
class User
|
@@ -37,7 +45,7 @@ draft_body = <<~'BODY'
|
|
37
45
|
user.greet
|
38
46
|
.end
|
39
47
|
|
40
|
-
## Elixir Code Example
|
48
|
+
## Elixir Code Example (Rouge)
|
41
49
|
|
42
50
|
.code elixir
|
43
51
|
defmodule Calculator do
|
@@ -62,7 +70,7 @@ draft_body = <<~'BODY'
|
|
62
70
|
IO.puts("5 + 3 = 8")
|
63
71
|
.end
|
64
72
|
|
65
|
-
## JavaScript Code Example
|
73
|
+
## JavaScript Code Example (Highlight.js)
|
66
74
|
|
67
75
|
.code javascript
|
68
76
|
class TodoList {
|
@@ -90,58 +98,70 @@ draft_body = <<~'BODY'
|
|
90
98
|
}
|
91
99
|
return todo;
|
92
100
|
}
|
93
|
-
|
94
|
-
removeTodo(id) {
|
95
|
-
const index = this.todos.findIndex(t => t.id === id);
|
96
|
-
if (index > -1) {
|
97
|
-
return this.todos.splice(index, 1)[0];
|
98
|
-
}
|
99
|
-
return null;
|
100
|
-
}
|
101
|
-
|
102
|
-
getCompletedTodos() {
|
103
|
-
return this.todos.filter(t => t.completed);
|
104
|
-
}
|
105
|
-
|
106
|
-
getPendingTodos() {
|
107
|
-
return this.todos.filter(t => !t.completed);
|
108
|
-
}
|
109
101
|
}
|
110
102
|
|
111
103
|
// Usage example
|
112
104
|
const todoList = new TodoList();
|
113
|
-
todoList.addTodo("Learn
|
105
|
+
todoList.addTodo("Learn syntax highlighting");
|
114
106
|
todoList.addTodo("Test multiple languages");
|
115
|
-
|
107
|
+
.end
|
108
|
+
|
109
|
+
## Simple Ruby Example
|
110
|
+
|
111
|
+
.code ruby
|
112
|
+
def hello_world
|
113
|
+
puts "Hello, World!"
|
114
|
+
@greeting = "Welcome to Scriptorium"
|
115
|
+
return @greeting
|
116
|
+
end
|
117
|
+
.end
|
116
118
|
|
117
|
-
|
118
|
-
|
119
|
+
## Plain Text Example
|
120
|
+
|
121
|
+
.code text
|
122
|
+
This is just plain text
|
123
|
+
No syntax highlighting needed
|
124
|
+
But it should still be in a code block
|
119
125
|
.end
|
120
126
|
|
121
127
|
## Test Results
|
122
128
|
|
123
129
|
Each code block above should display with proper syntax highlighting:
|
124
130
|
|
125
|
-
- **Ruby**: Keywords in red, strings in blue, variables in orange
|
126
|
-
- **Elixir**: Functions in purple, atoms in green, strings in blue
|
127
|
-
- **JavaScript**: Keywords in red, functions in purple, strings in blue
|
131
|
+
- **Ruby (Rouge)**: Keywords in red, strings in blue, variables in orange
|
132
|
+
- **Elixir (Rouge)**: Functions in purple, atoms in green, strings in blue
|
133
|
+
- **JavaScript (Highlight.js)**: Keywords in red, functions in purple, strings in blue
|
134
|
+
- **Plain text**: No highlighting, just code block formatting
|
128
135
|
|
129
|
-
|
136
|
+
Rouge and Highlight.js highlighting should work automatically!
|
130
137
|
BODY
|
131
138
|
|
132
|
-
name = @repo.create_draft(title: "
|
139
|
+
name = @repo.create_draft(title: "Comprehensive Syntax Highlighting Test", views: ["testview"], body: draft_body)
|
133
140
|
num = @repo.finish_draft(name)
|
134
141
|
@repo.generate_post(num)
|
135
142
|
|
136
143
|
@repo.generate_front_page("testview")
|
137
144
|
|
145
|
+
# Open the generated post directly (works under simple httpd without SPA)
|
146
|
+
unless ARGV.include?("--automated")
|
147
|
+
post_url = "http://127.0.0.1:8000/scriptorium-TEST/views/testview/output/posts/0001-comprehensive-syntax-highlighting-test.html"
|
148
|
+
puts "Press Enter to open the post directly to verify highlighting."
|
149
|
+
STDIN.gets
|
150
|
+
system("open #{post_url}")
|
151
|
+
end
|
152
|
+
|
138
153
|
instruct <<~EOS
|
139
|
-
Front page should have one post with
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
154
|
+
Front page should have one post with comprehensive syntax highlighting.
|
155
|
+
|
156
|
+
Highlight.js (Ruby, Elixir, JavaScript):
|
157
|
+
- Ruby/Elixir/JS: Token colors applied client-side
|
158
|
+
|
159
|
+
Plain text: No highlighting, just code block formatting
|
160
|
+
|
161
|
+
Check that Highlight.js CSS/JS are included in the generated HTML.
|
144
162
|
All code blocks should have proper token classes and syntax highlighting.
|
163
|
+
Then open the post directly to verify:
|
164
|
+
http://127.0.0.1:8000/scriptorium-TEST/views/testview/output/posts/0001-comprehensive-syntax-highlighting-test.html
|
145
165
|
EOS
|
146
166
|
|
147
|
-
examine("testview")
|
167
|
+
examine("testview")
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'shellwords'
|
3
|
+
|
4
|
+
module PreviewUtils
|
5
|
+
DEFAULT_CONFIG = {
|
6
|
+
"posts.per.page" => "5",
|
7
|
+
"entry.title.size" => "1.1em",
|
8
|
+
"entry.blurb.size" => "0.75em",
|
9
|
+
"entry.date.size" => "0.7em",
|
10
|
+
"entry.date.width" => "14%",
|
11
|
+
"entry.cellpadding" => "6",
|
12
|
+
"entry.margin.bottom" => "6px",
|
13
|
+
"entry.title.color" => "#000000",
|
14
|
+
"entry.blurb.color" => "#666666",
|
15
|
+
"entry.date.color" => "#888888",
|
16
|
+
"entry.line.height" => "1.1",
|
17
|
+
"entry.date.alignment"=> "right",
|
18
|
+
"entry.date.spacing" => "0.1em",
|
19
|
+
"entry.date.format" => "month dd break yyyy",
|
20
|
+
"index.margin.top" => "10px"
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
def self.write_post_index_config(repo_path, view_name, overrides = {})
|
24
|
+
config = DEFAULT_CONFIG.merge(overrides.transform_keys(&:to_s))
|
25
|
+
cfg_dir = File.join(repo_path, 'views', view_name, 'config')
|
26
|
+
FileUtils.mkdir_p(cfg_dir)
|
27
|
+
lines = config.map { |k,v| "#{k} #{v}" }.join("\n") + "\n"
|
28
|
+
File.write(File.join(cfg_dir, 'post_index.txt'), lines)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.seed_posts(api, titles_and_blurbs)
|
32
|
+
Array(titles_and_blurbs).each do |tb|
|
33
|
+
if tb.is_a?(Array)
|
34
|
+
api.create_post(tb[0], tb[1] || "")
|
35
|
+
else
|
36
|
+
api.create_post(tb.to_s, "")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.reference_image_in_post(repo_path, post_id4, filename)
|
42
|
+
src = File.join(repo_path, 'posts', post_id4, 'source.lt3')
|
43
|
+
File.write(src, ".image #{filename}\n\nHello")
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.paths(repo_path, view_name)
|
47
|
+
base = File.expand_path(File.join(repo_path, 'views', view_name))
|
48
|
+
index_file = File.join(base, 'output', 'index.html')
|
49
|
+
post_index = File.join(base, 'output', 'post_index.html')
|
50
|
+
page1 = File.join(base, 'output', 'page1.html')
|
51
|
+
|
52
|
+
# Try to find first post slug from 0001
|
53
|
+
slug = nil
|
54
|
+
meta = File.join(repo_path, 'posts', '0001', 'meta.txt')
|
55
|
+
if File.exist?(meta)
|
56
|
+
line = File.read(meta).lines.grep(/^post.slug\s+/).first
|
57
|
+
slug = line.split.last if line
|
58
|
+
end
|
59
|
+
post_html = slug ? File.join(base, 'output', 'posts', slug) : nil
|
60
|
+
|
61
|
+
{
|
62
|
+
index_file: index_file,
|
63
|
+
post_index: post_index,
|
64
|
+
page1: page1,
|
65
|
+
post_html: post_html,
|
66
|
+
preview_index_url: "http://localhost:4567/preview/#{view_name}/index.html",
|
67
|
+
preview_post_url: (slug ? "http://localhost:4567/preview/#{view_name}/posts/#{slug}" : nil)
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.interactive_open(label:, paths: [], urls: [])
|
72
|
+
puts "\n[Manual] Opening #{label}..."
|
73
|
+
# Always open local files
|
74
|
+
paths.compact.each do |target|
|
75
|
+
next if target.to_s.empty?
|
76
|
+
system("open #{Shellwords.escape(target)}")
|
77
|
+
end
|
78
|
+
# Also open server URLs (user asked to issue open commands)
|
79
|
+
urls.compact.each do |u|
|
80
|
+
next if u.to_s.empty?
|
81
|
+
system("open #{Shellwords.escape(u)}")
|
82
|
+
end
|
83
|
+
puts "[Manual] Press Enter to continue..."
|
84
|
+
STDIN.gets
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/scriptorium'
|
4
|
+
|
5
|
+
puts "=== Scriptorium Gem Asset Test ==="
|
6
|
+
puts "Gem version: #{Scriptorium::VERSION}"
|
7
|
+
puts
|
8
|
+
|
9
|
+
# Test that we can access the StandardFiles class
|
10
|
+
predef = Scriptorium::StandardFiles.new
|
11
|
+
puts "✅ StandardFiles class accessible"
|
12
|
+
|
13
|
+
# Test post template generation
|
14
|
+
template = predef.support_data('templates/post.lt3')
|
15
|
+
puts "✅ Post template generated (#{template.lines.count} lines)"
|
16
|
+
|
17
|
+
# Test that clipboard function is in common.js
|
18
|
+
common_js = predef.common_js
|
19
|
+
if common_js.include?('copyPermalinkToClipboard')
|
20
|
+
puts "✅ Clipboard function found in common.js"
|
21
|
+
else
|
22
|
+
puts "❌ Clipboard function NOT found in common.js"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Test template with variables
|
26
|
+
vars = {
|
27
|
+
:'post.title' => 'Test Post',
|
28
|
+
:'post.pubdate' => '2025-08-14',
|
29
|
+
:'post.date' => '2025-08-14',
|
30
|
+
:'post.tags' => 'test, gem',
|
31
|
+
:'post.body' => 'This is a test post from the installed gem.',
|
32
|
+
:reddit_button => ''
|
33
|
+
}
|
34
|
+
|
35
|
+
result = template % vars
|
36
|
+
puts "✅ Template variable substitution works"
|
37
|
+
puts "✅ Generated HTML contains copy button: #{result.include?('copyPermalinkToClipboard')}"
|
38
|
+
|
39
|
+
# Test that the copy button is present
|
40
|
+
if result.include?('Copy link')
|
41
|
+
puts "✅ Copy link button present in generated HTML"
|
42
|
+
else
|
43
|
+
puts "❌ Copy link button NOT present in generated HTML"
|
44
|
+
end
|
45
|
+
|
46
|
+
puts
|
47
|
+
puts "=== Asset Test Complete ==="
|
48
|
+
puts "All gem assets are working correctly!"
|
data/test/test_helpers.rb
CHANGED
@@ -27,6 +27,16 @@ module TestHelpers
|
|
27
27
|
assert lines.size == num, "Expected #{num} lines in #{file}; found #{lines.size}"
|
28
28
|
end
|
29
29
|
|
30
|
+
# Assert that a string includes text, with concise error message
|
31
|
+
def assert_includes_concise_string(content, text, description)
|
32
|
+
unless content.include?(text)
|
33
|
+
# Show content size and a snippet for debugging
|
34
|
+
size = content.size
|
35
|
+
snippet = content[0, 300].gsub(/\s+/, ' ').strip
|
36
|
+
flunk "#{description} - Expected to find '#{text}' in content (#{size} bytes). Content snippet: #{snippet}..."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
30
40
|
def assert_file_newer?(f1, f2)
|
31
41
|
assert File.mtime(f1) > File.mtime(f2), "File #{f1} is not newer than #{f2}"
|
32
42
|
end
|
@@ -27,7 +27,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
27
27
|
|
28
28
|
ENV['NOREADLINE'] = '1'
|
29
29
|
|
30
|
-
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium') do |read, write, pid|
|
30
|
+
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium --test') do |read, write, pid|
|
31
31
|
begin
|
32
32
|
run_links_widget_workflow(read, write)
|
33
33
|
ensure
|
@@ -44,7 +44,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
44
44
|
# Test basic TUI flow without complex wizard
|
45
45
|
ENV['NOREADLINE'] = '1'
|
46
46
|
|
47
|
-
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium') do |read, write, pid|
|
47
|
+
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium --test') do |read, write, pid|
|
48
48
|
begin
|
49
49
|
run_basic_tui_workflow(read, write)
|
50
50
|
|
@@ -62,7 +62,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
62
62
|
# Test creating a post through the TUI
|
63
63
|
ENV['NOREADLINE'] = '1'
|
64
64
|
|
65
|
-
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium') do |read, write, pid|
|
65
|
+
PTY.spawn({'NOREADLINE' => '1'}, 'ruby bin/scriptorium --test') do |read, write, pid|
|
66
66
|
begin
|
67
67
|
run_create_post_workflow(read, write)
|
68
68
|
ensure
|
@@ -84,10 +84,10 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
84
84
|
if output
|
85
85
|
puts "Found: #{output[0].strip}" if ENV['VERBOSE']
|
86
86
|
else
|
87
|
-
|
87
|
+
# Pattern not found
|
88
88
|
# Read what we actually got
|
89
89
|
available = read.read_nonblock(1000) rescue ""
|
90
|
-
|
90
|
+
# Available output logged above
|
91
91
|
end
|
92
92
|
assert output, message
|
93
93
|
output[0] # Return the matched string
|
@@ -126,7 +126,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
126
126
|
get_string(read, /No repository found\./, "Should show 'No repository found'")
|
127
127
|
|
128
128
|
# Send 'y' to create new repository
|
129
|
-
send_and_expect(read, write, "y", "Created repository successfully.",
|
129
|
+
send_and_expect(read, write, "y", "Created test repository successfully.",
|
130
130
|
"Should show repository created")
|
131
131
|
|
132
132
|
# Wait for editor setup
|
@@ -144,18 +144,18 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
144
144
|
get_string(read, "Setup complete", "Should show setup completion")
|
145
145
|
|
146
146
|
# Wait for assistance question
|
147
|
-
get_string(read,
|
147
|
+
get_string(read, /Do you want assistance/, "Should ask about assistance")
|
148
148
|
|
149
149
|
# Send 'y' for assistance
|
150
|
-
send_and_expect(read, write, "y",
|
150
|
+
send_and_expect(read, write, "y", /Enter view name/,
|
151
151
|
"Should prompt for view name")
|
152
152
|
|
153
153
|
# Send view name
|
154
|
-
send_and_expect(read, write, "testview",
|
154
|
+
send_and_expect(read, write, "testview", /Enter view title/,
|
155
155
|
"Should prompt for view title")
|
156
156
|
|
157
157
|
# Send view title
|
158
|
-
send_and_expect(read, write, "Test View",
|
158
|
+
send_and_expect(read, write, "Test View", /Enter subtitle/,
|
159
159
|
"Should prompt for subtitle")
|
160
160
|
|
161
161
|
# Send subtitle
|
@@ -211,7 +211,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
211
211
|
get_string(read, "No repository found.", "Should show 'No repository found'")
|
212
212
|
|
213
213
|
# Send 'y' to create new repository
|
214
|
-
send_and_expect(read, write, "y", "Created repository successfully.",
|
214
|
+
send_and_expect(read, write, "y", "Created test repository successfully.",
|
215
215
|
"Should show repository created")
|
216
216
|
|
217
217
|
# Wait for editor setup
|
@@ -229,7 +229,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
229
229
|
get_string(read, "Setup complete", "Should show setup completion")
|
230
230
|
|
231
231
|
# Wait for assistance question
|
232
|
-
get_string(read,
|
232
|
+
get_string(read, /Do you want assistance/, "Should ask about assistance")
|
233
233
|
|
234
234
|
# Send 'n' to skip assistance
|
235
235
|
send_and_expect(read, write, "n", "[sample]", "Should show main prompt")
|
@@ -244,7 +244,7 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
244
244
|
get_string(read, "No repository found.", "Should show 'No repository found'")
|
245
245
|
|
246
246
|
# Send 'y' to create new repository
|
247
|
-
send_and_expect(read, write, "y", "Created repository successfully.",
|
247
|
+
send_and_expect(read, write, "y", "Created test repository successfully.",
|
248
248
|
"Should show repository created")
|
249
249
|
|
250
250
|
# Wait for editor setup
|
@@ -262,13 +262,13 @@ class TUIEditorIntegrationTest < Minitest::Test
|
|
262
262
|
get_string(read, "Setup complete", "Should show setup completion")
|
263
263
|
|
264
264
|
# Wait for assistance question
|
265
|
-
get_string(read,
|
265
|
+
get_string(read, /Do you want assistance/, "Should ask about assistance")
|
266
266
|
|
267
267
|
# Send 'n' to skip assistance
|
268
268
|
send_and_expect(read, write, "n", "[sample]", "Should show main prompt")
|
269
269
|
|
270
270
|
# Create a post
|
271
|
-
send_and_expect(read, write, "new post Test Post",
|
271
|
+
send_and_expect(read, write, "new post Test Post", /Created draft:/,
|
272
272
|
"Should show draft created")
|
273
273
|
|
274
274
|
# Wait for editor opening
|