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
@@ -21,187 +21,28 @@ class Scriptorium::StandardFiles
|
|
21
21
|
javascript # See common.js
|
22
22
|
bootstrap # See bootstrap.txt
|
23
23
|
social # See social.txt for configuration
|
24
|
+
highlight # See highlight_css.txt for syntax highlighting
|
25
|
+
highlight_custom # Custom CSS overrides for Highlight.js
|
24
26
|
EOS
|
27
|
+
str
|
25
28
|
end
|
26
29
|
|
27
30
|
def common_js
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
load_main(event.state.slug); // Load the post for the previous history state
|
35
|
-
}
|
36
|
-
};
|
37
|
-
|
38
|
-
// Initialize with the front page when navigating via the back button or similar
|
39
|
-
window.onload = function() {
|
40
|
-
// Check if the URL has a post parameter and load it automatically
|
41
|
-
const urlParams = new URLSearchParams(window.location.search);
|
42
|
-
const postParam = urlParams.get('post');
|
43
|
-
|
44
|
-
if (postParam) {
|
45
|
-
// URL has a post parameter, load the post content
|
46
|
-
console.log('Auto-loading post from URL parameter:', postParam);
|
47
|
-
load_main('index.html?post=' + postParam);
|
48
|
-
return;
|
49
|
-
}
|
31
|
+
files = [
|
32
|
+
'common_js/navigation.js',
|
33
|
+
'common_js/content-loader.js',
|
34
|
+
'common_js/syntax-highlighting.js',
|
35
|
+
'common_js/clipboard.js'
|
36
|
+
]
|
50
37
|
|
51
|
-
|
52
|
-
if (!history.state) {
|
53
|
-
// Don't try to load post_index.html if there are no posts
|
54
|
-
// The "No posts yet!" message is already in the main container
|
55
|
-
history.replaceState({ slug: "index.html" }, "", "index.html");
|
56
|
-
}
|
57
|
-
|
58
|
-
|
59
|
-
};
|
60
|
-
|
61
|
-
// Load the main content and other page containers (header, footer, left, right)
|
62
|
-
function load_main(slug) {
|
63
|
-
// Get all container elements (header, footer, left, right, and main)
|
64
|
-
const contentDiv = document.getElementById("main");
|
65
|
-
const headerDiv = document.querySelector("header");
|
66
|
-
const footerDiv = document.querySelector("footer");
|
67
|
-
const leftDiv = document.querySelector(".left");
|
68
|
-
const rightDiv = document.querySelector(".right");
|
69
|
-
console.log('Loading main with slug:', slug); // Log the slug
|
70
|
-
|
71
|
-
// Check if this is a post parameter request
|
72
|
-
if (slug.includes('?post=')) {
|
73
|
-
const postSlug = slug.split('?post=')[1];
|
74
|
-
console.log('Loading post:', postSlug);
|
75
|
-
|
76
|
-
// Load the post content - add .html extension if it's missing
|
77
|
-
const postFile = postSlug.endsWith('.html') ? postSlug : postSlug + '.html';
|
78
|
-
fetch('posts/' + postFile)
|
79
|
-
.then(response => {
|
80
|
-
if (response.ok) {
|
81
|
-
return response.text();
|
82
|
-
} else {
|
83
|
-
console.error('Failed to load post:', response.status);
|
84
|
-
return 'Post not found';
|
85
|
-
}
|
86
|
-
})
|
87
|
-
.then(content => {
|
88
|
-
contentDiv.innerHTML = content;
|
89
|
-
history.pushState({slug: 'index.html?post=' + postSlug}, "", 'index.html?post=' + postSlug);
|
90
|
-
})
|
91
|
-
.catch(error => {
|
92
|
-
console.log("Error loading post:", error);
|
93
|
-
contentDiv.innerHTML = 'Error loading post';
|
94
|
-
});
|
95
|
-
return;
|
96
|
-
}
|
97
|
-
|
98
|
-
// Check if this is a static page request (pages/, assets/, etc.)
|
99
|
-
if (slug.startsWith('pages/') || slug.startsWith('assets/') || slug.includes('/')) {
|
100
|
-
console.log('Loading static page:', slug);
|
101
|
-
// Simple approach: always go back to index.html directory and fetch from there
|
102
|
-
fetch(slug)
|
103
|
-
.then(response => {
|
104
|
-
if (response.ok) {
|
105
|
-
return response.text();
|
106
|
-
} else {
|
107
|
-
console.error('Failed to load static page:', response.status);
|
108
|
-
return 'Page not found';
|
109
|
-
}
|
110
|
-
})
|
111
|
-
.then(content => {
|
112
|
-
contentDiv.innerHTML = content;
|
113
|
-
// Don't change the URL for static pages to avoid path resolution issues
|
114
|
-
history.pushState({slug: slug}, "", window.location.pathname);
|
115
|
-
})
|
116
|
-
.catch(error => {
|
117
|
-
console.log("Error loading static page:", error);
|
118
|
-
contentDiv.innerHTML = 'Error loading page';
|
119
|
-
});
|
120
|
-
return;
|
121
|
-
}
|
122
|
-
|
123
|
-
fetch(slug)
|
124
|
-
.then(response => {
|
125
|
-
if (response.ok) {
|
126
|
-
console.log('Response is ok');
|
127
|
-
return response.text();
|
128
|
-
} else {
|
129
|
-
console.error('Failed to load:', response.status); // Log the failed response
|
130
|
-
}
|
131
|
-
})
|
132
|
-
.then(content => {
|
133
|
-
console.log('Loaded content into div'); // Log successful content insertion
|
134
|
-
|
135
|
-
// Now, reload the content into the respective containers:
|
136
|
-
// Main section
|
137
|
-
contentDiv.innerHTML = content;
|
138
|
-
|
139
|
-
// Re-insert header, footer, left, and right (if necessary)
|
140
|
-
// If you want the static layout to be kept, you can preserve these parts
|
141
|
-
// with additional logic or predefined structure (here it's assumed
|
142
|
-
// that header/footer/left/right are already statically included).
|
143
|
-
|
144
|
-
// You can also replace the other parts (left, right, header, footer) if needed.
|
145
|
-
history.pushState({slug: slug}, "", slug); // Update browser history
|
146
|
-
|
147
|
-
|
148
|
-
})
|
149
|
-
.catch(error => {
|
150
|
-
console.log("Error loading content:", error); // Log any errors during fetch
|
151
|
-
});
|
152
|
-
}
|
153
|
-
|
154
|
-
// Copy permalink to clipboard functionality
|
155
|
-
function copyPermalinkToClipboard() {
|
156
|
-
// Get the current post slug from the URL or construct it
|
157
|
-
const currentUrl = window.location.href;
|
158
|
-
let permalinkUrl;
|
159
|
-
|
160
|
-
if (currentUrl.includes('?post=')) {
|
161
|
-
// We're on the main blog page, construct the permalink URL
|
162
|
-
const postSlug = currentUrl.split('?post=')[1];
|
163
|
-
const baseUrl = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '');
|
164
|
-
permalinkUrl = baseUrl + '/permalink/' + postSlug;
|
165
|
-
} else {
|
166
|
-
// We're already on a permalink page, use current URL
|
167
|
-
permalinkUrl = currentUrl;
|
168
|
-
}
|
169
|
-
|
170
|
-
navigator.clipboard.writeText(permalinkUrl).then(function() {
|
171
|
-
// Change button text temporarily to show success
|
172
|
-
const button = event.target;
|
173
|
-
const originalText = button.textContent;
|
174
|
-
button.textContent = 'Copied!';
|
175
|
-
button.style.background = '#28a745';
|
176
|
-
setTimeout(function() {
|
177
|
-
button.textContent = originalText;
|
178
|
-
button.style.background = '#007bff';
|
179
|
-
}, 2000);
|
180
|
-
}).catch(function(err) {
|
181
|
-
console.error('Failed to copy: ', err);
|
182
|
-
alert('Failed to copy link to clipboard');
|
183
|
-
});
|
184
|
-
}
|
185
|
-
EOS
|
38
|
+
files.map { |file| support_data(file) }.join("\n\n")
|
186
39
|
end
|
187
40
|
|
188
41
|
|
189
|
-
def bootstrap_css
|
190
|
-
<<~EOS
|
191
|
-
href https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css
|
192
|
-
rel stylesheet
|
193
|
-
# integrity has a problem - compute instead?
|
194
|
-
# integrity sha384-KyZXEJ04F5o1v7V5b7ZMjGhGjxA8yQmBfvZwzI1r+0gEv+9KnQIMJxWwzD0u8nZ7
|
195
|
-
# crossorigin anonymous
|
196
|
-
EOS
|
197
|
-
end
|
198
42
|
|
199
|
-
def
|
43
|
+
def highlight_ruby_js
|
200
44
|
<<~EOS
|
201
|
-
src https://
|
202
|
-
# integrity has a problem - compute instead?
|
203
|
-
# integrity sha384-pzjw8f+ua7Kw1TIq0+v5+GZkR6P/6v03cI0myXcJU22Hc5p5BY5/X93HmaJXjm4C
|
204
|
-
crossorigin anonymous
|
45
|
+
src https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/ruby.min.js
|
205
46
|
EOS
|
206
47
|
end
|
207
48
|
|
@@ -213,32 +54,6 @@ class Scriptorium::StandardFiles
|
|
213
54
|
EOS
|
214
55
|
end
|
215
56
|
|
216
|
-
def social_config
|
217
|
-
<<~EOS
|
218
|
-
# Available platforms: facebook twitter linkedin reddit
|
219
|
-
# List one platform per line to enable social meta tags
|
220
|
-
facebook
|
221
|
-
twitter
|
222
|
-
|
223
|
-
# Note: No Facebook App ID or Twitter username required for basic meta tags
|
224
|
-
# These are only needed if you want to add social sharing buttons later
|
225
|
-
EOS
|
226
|
-
end
|
227
|
-
|
228
|
-
def reddit_config
|
229
|
-
<<~EOS
|
230
|
-
# Reddit sharing button configuration
|
231
|
-
# Set to true to show Reddit share button on posts
|
232
|
-
button true
|
233
|
-
|
234
|
-
# Optional: specify a subreddit for direct posting
|
235
|
-
# Leave empty or omit to let users choose subreddit
|
236
|
-
subreddit
|
237
|
-
|
238
|
-
# Optional: custom hover text (defaults to "Share on Reddit" or "Share on [subreddit]")
|
239
|
-
hover_text
|
240
|
-
EOS
|
241
|
-
end
|
242
57
|
|
243
58
|
def initial_post(mode = :filled, num: "0", title: nil, blurb: nil, views: nil,
|
244
59
|
tags: nil, body: nil)
|
@@ -249,50 +64,16 @@ class Scriptorium::StandardFiles
|
|
249
64
|
tags ||= %w[sample tags]
|
250
65
|
body ||= "BEGIN HERE..."
|
251
66
|
|
252
|
-
str =
|
253
|
-
<<~EOS
|
254
|
-
. Initial file created by StandardFiles#post_template(num)
|
255
|
-
|
256
|
-
.id %{num}
|
257
|
-
.created %{created}
|
258
|
-
|
259
|
-
.title %{title}
|
260
|
-
.blurb %{blurb}
|
261
|
-
|
262
|
-
.views %{views}
|
263
|
-
.tags %{tags}
|
264
|
-
|
265
|
-
#{body}
|
266
|
-
EOS
|
67
|
+
str = support_data('templates/initial_post.lt3')
|
267
68
|
|
268
69
|
return str if mode == :raw
|
269
70
|
mytags = tags
|
270
71
|
mytags = tags.join(", ") if tags.is_a?(Array)
|
271
72
|
str2 = str % {num: d4(num.to_i), created: ymdhms, title: title, blurb: blurb,
|
272
|
-
views: views.join(" "), tags: mytags}
|
73
|
+
views: views.join(" "), tags: mytags, body: body}
|
273
74
|
return str2
|
274
75
|
end
|
275
76
|
|
276
|
-
def initial_post_content(title: nil, blurb: nil, views: nil, tags: nil, body: nil)
|
277
|
-
title ||= "ADD TITLE HERE"
|
278
|
-
blurb ||= "ADD BLURB HERE"
|
279
|
-
views ||= %w[sample]
|
280
|
-
tags ||= %w[sample tags]
|
281
|
-
body ||= "BEGIN HERE..."
|
282
|
-
|
283
|
-
mytags = tags
|
284
|
-
mytags = tags.join(", ") if tags.is_a?(Array)
|
285
|
-
|
286
|
-
<<~EOS
|
287
|
-
.title #{title}
|
288
|
-
.blurb #{blurb}
|
289
|
-
.views #{views.join(" ")}
|
290
|
-
.tags #{mytags}
|
291
|
-
|
292
|
-
#{body}
|
293
|
-
EOS
|
294
|
-
end
|
295
|
-
|
296
77
|
def initial_post_metadata(num: "0", title: nil, blurb: nil, views: nil, tags: nil)
|
297
78
|
title ||= "ADD TITLE HERE"
|
298
79
|
blurb ||= "ADD BLURB HERE"
|
@@ -314,159 +95,12 @@ class Scriptorium::StandardFiles
|
|
314
95
|
EOS
|
315
96
|
end
|
316
97
|
|
317
|
-
def
|
318
|
-
|
319
|
-
<!-- theme: #{theme} -->
|
320
|
-
|
321
|
-
<div align='right'><a style="text-decoration: none" href="index.html">
|
322
|
-
<img src="assets/back-icon.png" width=24 height=24 alt="Go to Index"></img></a>
|
323
|
-
</div>
|
324
|
-
<div style="display: flex; justify-content: space-between; align-items: baseline;">
|
325
|
-
<span style="text-align: left; font-size: 1.5em;">%{post.title}</span>
|
326
|
-
<span style="text-align: right; font-size: 0.9em;">%{reddit_button}%{post.pubdate}</span>
|
327
|
-
</div>
|
328
|
-
<hr>
|
329
|
-
%{post.body}
|
330
|
-
<hr>
|
331
|
-
<div style="text-align: right; font-size: 0.8em;">%{post.tags}</div>
|
332
|
-
<div style="text-align: center; margin-top: 20px;">
|
333
|
-
<button onclick="copyPermalinkToClipboard()" style="padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">Copy link</button>
|
334
|
-
</div>
|
335
|
-
EOS
|
336
|
-
end
|
337
|
-
|
338
|
-
def layout_text
|
339
|
-
<<~EOS
|
340
|
-
header # Top (banner? title? navbar? etc.)
|
341
|
-
left 15% # Left sidebar, 15% width
|
342
|
-
main # Main (center) container - posts/etc.
|
343
|
-
right 15% # Right sidebar, 15% width
|
344
|
-
footer # Footer (copyright? mail? social media? etc.)
|
345
|
-
EOS
|
346
|
-
end
|
347
|
-
|
348
|
-
def post_index_style # Not really a file
|
349
|
-
<<~EOS
|
350
|
-
<style>
|
351
|
-
body { font-family: verdana }
|
352
|
-
|
353
|
-
.recent-title a {
|
354
|
-
color: #010101;
|
355
|
-
font-family: verdana;
|
356
|
-
font-size: 28px;
|
357
|
-
float: right;
|
358
|
-
display: inline-block;
|
359
|
-
text-align: top;
|
360
|
-
text-decoration: none;
|
361
|
-
}
|
362
|
-
|
363
|
-
.recent-title a:hover {
|
364
|
-
text-decoration: none;
|
365
|
-
}
|
366
|
-
|
367
|
-
.recent-title-text a {
|
368
|
-
color: #0101a1;
|
369
|
-
font-family: verdana;
|
370
|
-
font-size: 22px;
|
371
|
-
display: block;
|
372
|
-
text-decoration: none;
|
373
|
-
}
|
374
|
-
|
375
|
-
.recent-title-text a:hover {
|
376
|
-
text-decoration: none;
|
377
|
-
}
|
378
|
-
|
379
|
-
.recent-date {
|
380
|
-
color: #9a9a9a;
|
381
|
-
font-family: verdana;
|
382
|
-
font-size: 15px;
|
383
|
-
display: block;
|
384
|
-
float: left;
|
385
|
-
text-align: top;
|
386
|
-
}
|
387
|
-
|
388
|
-
.mydrop {
|
389
|
-
color: #444444;
|
390
|
-
float: left;
|
391
|
-
text-align: top;
|
392
|
-
# font-family: Verdana;
|
393
|
-
font-size: 38px;
|
394
|
-
line-height: 38px;
|
395
|
-
# padding-top: 0px;
|
396
|
-
padding-right: 8px;
|
397
|
-
padding-left: 3px;
|
398
|
-
}
|
399
|
-
|
400
|
-
.thumbnail img {
|
401
|
-
max-height: 100%;
|
402
|
-
max-width: 100%;
|
403
|
-
}
|
404
|
-
</style>
|
405
|
-
EOS
|
406
|
-
end
|
407
|
-
|
408
|
-
# <!-- posts/%{post.slug}" -->
|
409
|
-
|
410
|
-
def index_entry
|
411
|
-
# Note the use of %% to escape the % in the flex-basis attribute!
|
412
|
-
<<~EOS
|
413
|
-
<div class="index-entry" style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;">
|
414
|
-
<!-- Left Side: Date (right aligned) -->
|
415
|
-
<div style="text-align: right; font-size: 0.7em; flex-basis: 10%%; padding-top: 3px;">
|
416
|
-
<div>%{post.pubdate.month} %{post.pubdate.day}</div>
|
417
|
-
<div>%{post.pubdate.year}</div>
|
418
|
-
</div>
|
419
|
-
<!-- Right Side: Title and Blurb (left aligned) -->
|
420
|
-
<div style="font-size: 1.2em; margin-left: 10px; flex-grow: 1; padding-top: 0;">
|
421
|
-
<div><a href="javascript:void(0)"
|
422
|
-
style="text-decoration: none;"
|
423
|
-
onclick="load_main('index.html?post=%{post.slug}')">%{post.title}</a></div>
|
424
|
-
<div style="font-size: 0.9em;">%{post.blurb}</div>
|
425
|
-
</div>
|
426
|
-
</div>
|
427
|
-
EOS
|
428
|
-
end
|
429
|
-
|
430
|
-
def theme_header # Add theme name to these files??
|
431
|
-
<<~EOS
|
432
|
-
# <!-- Section: header -->
|
433
|
-
# Contents of header
|
434
|
-
# (may include banner, title, navbar, ...)
|
435
|
-
title
|
436
|
-
EOS
|
437
|
-
end
|
438
|
-
|
439
|
-
def theme_footer
|
440
|
-
<<~EOS
|
441
|
-
# <!-- Section: footer -->
|
442
|
-
# Contents of footer
|
443
|
-
EOS
|
444
|
-
end
|
445
|
-
|
446
|
-
def theme_left
|
447
|
-
<<~EOS
|
448
|
-
# <!-- Section: left -->
|
449
|
-
# Contents of left sidebar
|
450
|
-
# (may be widgets or whatever)
|
451
|
-
EOS
|
452
|
-
end
|
453
|
-
|
454
|
-
def theme_right
|
455
|
-
<<~EOS
|
456
|
-
# <!-- Section: right -->
|
457
|
-
# Contents of right sidebar
|
458
|
-
# (may be widgets or whatever)
|
459
|
-
EOS
|
98
|
+
def support_data(relative_path)
|
99
|
+
read_file(support_file(relative_path))
|
460
100
|
end
|
461
101
|
|
462
|
-
def
|
463
|
-
|
464
|
-
# <!-- Section: main -->
|
465
|
-
# Contents of center pane
|
466
|
-
# This may be empty, as it is "usually" populated
|
467
|
-
# by Javascript (list of recent posts, content from
|
468
|
-
# a widget, or whatever)
|
469
|
-
EOS
|
102
|
+
def post_template
|
103
|
+
support_data('templates/post.lt3')
|
470
104
|
end
|
471
105
|
|
472
106
|
def svg_txt
|
@@ -477,13 +111,13 @@ class Scriptorium::StandardFiles
|
|
477
111
|
subtitle.color #cccccc
|
478
112
|
text.justify left
|
479
113
|
|
480
|
-
title.scale 0.
|
481
|
-
subtitle.scale 0.
|
114
|
+
title.scale 0.8
|
115
|
+
subtitle.scale 0.4
|
482
116
|
|
483
117
|
title.style bold
|
484
118
|
subtitle.style bold italic
|
485
|
-
title.xy
|
486
|
-
subtitle.xy
|
119
|
+
title.xy 5 50
|
120
|
+
subtitle.xy 5 75
|
487
121
|
|
488
122
|
back.linear #0000cc #000077 lr
|
489
123
|
|
@@ -503,13 +137,13 @@ class Scriptorium::StandardFiles
|
|
503
137
|
|
504
138
|
def status_txt
|
505
139
|
<<~EOS
|
506
|
-
header
|
507
|
-
banner
|
508
|
-
navbar
|
509
|
-
left
|
510
|
-
right
|
511
|
-
pages
|
512
|
-
deploy
|
140
|
+
header n
|
141
|
+
banner n
|
142
|
+
navbar n
|
143
|
+
left n
|
144
|
+
right n
|
145
|
+
pages n
|
146
|
+
deploy n
|
513
147
|
EOS
|
514
148
|
end
|
515
|
-
end
|
149
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
// Copy permalink to clipboard functionality
|
2
|
+
function copyPermalinkToClipboard(button) {
|
3
|
+
// Get the current post slug from the URL or construct it
|
4
|
+
const currentUrl = window.location.href;
|
5
|
+
let permalinkUrl;
|
6
|
+
|
7
|
+
if (currentUrl.includes('?post=')) {
|
8
|
+
// We're on the main blog page, construct the permalink URL
|
9
|
+
const postSlug = currentUrl.split('?post=')[1];
|
10
|
+
// const baseUrl = window.location.origin + window.location.pathname.replace(/\\[^\\/]*$/, '');
|
11
|
+
const parts = window.location.pathname.split('/');
|
12
|
+
parts.pop();
|
13
|
+
const baseUrl = window.location.origin + parts.join('/') + '/';
|
14
|
+
permalinkUrl = baseUrl + 'permalink/' + postSlug;
|
15
|
+
} else {
|
16
|
+
// We're already on a permalink page, use current URL
|
17
|
+
permalinkUrl = currentUrl;
|
18
|
+
}
|
19
|
+
|
20
|
+
navigator.clipboard.writeText(permalinkUrl).then(function() {
|
21
|
+
// Change button text temporarily to show success
|
22
|
+
const btn = button || document.activeElement || document.querySelector('button[onclick*="copyPermalinkToClipboard"]');
|
23
|
+
if (!btn) { return; }
|
24
|
+
const originalText = btn.textContent;
|
25
|
+
btn.textContent = 'Copied!';
|
26
|
+
btn.style.background = '#28a745';
|
27
|
+
setTimeout(function() {
|
28
|
+
btn.textContent = originalText;
|
29
|
+
btn.style.background = '#007bff';
|
30
|
+
}, 2000);
|
31
|
+
}).catch(function(err) {
|
32
|
+
console.error('Failed to copy: ', err);
|
33
|
+
alert('Failed to copy link to clipboard');
|
34
|
+
});
|
35
|
+
}
|