scriptorium 0.0.2 → 0.6.1
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/back-icon.png +0 -0
- data/assets/icons/facebook.svg +1 -0
- data/assets/icons/github.svg +1 -0
- data/assets/icons/instagram.svg +1 -0
- data/assets/icons/reddit.svg +1 -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/icons/x.svg +1 -0
- data/assets/icons/youtube.svg +1 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/scriptorium +1511 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +95 -0
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +34 -0
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +50 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +31 -0
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +73 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +64 -0
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +70 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +110 -0
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +73 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +124 -0
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +46 -0
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +97 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +211 -0
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +141 -0
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +211 -0
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +134 -0
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +41 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +45 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +30 -0
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +49 -0
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +46 -0
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +256 -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/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +38 -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/doc/userdoc-toc.txt +88 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +640 -0
- data/lib/scriptorium/banner_svg.rb +742 -0
- data/lib/scriptorium/contract.rb +33 -0
- data/lib/scriptorium/exceptions.rb +174 -0
- data/lib/scriptorium/helpers.rb +475 -0
- data/lib/scriptorium/post.rb +195 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +624 -0
- data/lib/scriptorium/standard_files.rb +515 -0
- data/lib/scriptorium/syntax_highlighter.rb +234 -0
- data/lib/scriptorium/theme.rb +179 -0
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +976 -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 +22 -9
- data/lib/skeleton.rb +11 -2
- data/scriptorium.gemspec +15 -4
- data/test/README.md +69 -0
- data/test/all +43 -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 +768 -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/livetext_plugin_test.rb +229 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/config.txt +3 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/test01.html +58 -0
- data/test/manual/banner-tests/test02.html +58 -0
- data/test/manual/banner-tests/test03.html +58 -0
- data/test/manual/banner-tests/test04.html +65 -0
- data/test/manual/banner-tests/test05.html +65 -0
- data/test/manual/banner-tests/test06.html +65 -0
- data/test/manual/banner-tests/test07.html +65 -0
- data/test/manual/banner-tests/test08.html +59 -0
- data/test/manual/banner-tests/test09.html +59 -0
- data/test/manual/banner-tests/test10.html +59 -0
- data/test/manual/banner-tests/test11.html +59 -0
- data/test/manual/banner-tests/test12.html +59 -0
- data/test/manual/banner-tests/test13.html +59 -0
- data/test/manual/banner-tests/test14.html +59 -0
- data/test/manual/banner-tests/test15.html +58 -0
- data/test/manual/banner-tests/test16.html +58 -0
- data/test/manual/banner-tests/test17.html +58 -0
- data/test/manual/banner-tests/test18.html +68 -0
- data/test/manual/banner-tests/test19.html +68 -0
- data/test/manual/banner-tests/test20.html +68 -0
- data/test/manual/banner-tests/test21.html +68 -0
- data/test/manual/banner-tests/test22.html +68 -0
- data/test/manual/banner-tests/test23.html +68 -0
- data/test/manual/banner-tests/test24.html +68 -0
- data/test/manual/banner-tests/test25.html +67 -0
- data/test/manual/banner_environment.rb +192 -0
- data/test/manual/deploy_symlink_demo.rb +142 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/symlink_demo.rb +117 -0
- data/test/manual/test1.rb +47 -0
- data/test/manual/test2.rb +12 -0
- data/test/manual/test3.rb +38 -0
- data/test/manual/test4.rb +40 -0
- data/test/manual/test5.rb +24 -0
- data/test/manual/test6.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_from_file.rb +150 -0
- data/test/manual/test_banner_in_header.rb +35 -0
- data/test/manual/test_code_highlighting.rb +68 -0
- data/test/manual/test_complex_header.rb +74 -0
- data/test/manual/test_empty_header.rb +32 -0
- data/test/manual/test_radial_custom.rb +58 -0
- data/test/manual/test_radial_large_radius.rb +52 -0
- data/test/manual/test_svg_debug.rb +47 -0
- data/test/manual/test_syntax_highlighting.rb +147 -0
- data/test/pages-demo/config/currentview.txt +1 -0
- data/test/pages-demo/views/demo/config/bootstrap_css.txt +5 -0
- data/test/pages-demo/views/demo/config/bootstrap_js.txt +4 -0
- data/test/pages-demo/views/demo/config/common.js +57 -0
- data/test/pages-demo/views/demo/config/footer.txt +1 -0
- data/test/pages-demo/views/demo/config/global-head.txt +8 -0
- data/test/pages-demo/views/demo/config/header.txt +1 -0
- data/test/pages-demo/views/demo/config/layout.txt +1 -0
- data/test/pages-demo/views/demo/config/left.txt +1 -0
- data/test/pages-demo/views/demo/config/main.txt +1 -0
- data/test/pages-demo/views/demo/config/right.txt +1 -0
- data/test/pages-demo/views/demo/config.txt +3 -0
- data/test/pages-demo/views/demo/output/panes/footer.html +1 -0
- data/test/pages-demo/views/demo/output/panes/header.html +1 -0
- data/test/pages-demo/views/demo/output/panes/left.html +1 -0
- data/test/pages-demo/views/demo/output/panes/main.html +1 -0
- data/test/pages-demo/views/demo/output/panes/right.html +1 -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/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +8 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +6 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 +12 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +14 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +13 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/reddit.txt +10 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/social.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +1 -0
- data/test/staging/.DS_Store +0 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_helpers.rb +230 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +637 -0
- data/test/unit/api.rb +1056 -0
- data/test/unit/asset_management.rb +245 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +91 -0
- data/test/unit/core.rb +857 -0
- data/test/unit/deploy_test.rb +187 -0
- data/test/unit/gem_asset_management.rb +189 -0
- data/test/unit/livetext_basic.rb +69 -0
- data/test/unit/livetext_compatibility.rb +89 -0
- data/test/unit/post.rb +244 -0
- data/test/unit/read_commented_file_test.rb +276 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +548 -0
- data/test/unit/social_test.rb +369 -0
- data/test/unit/symlink_test.rb +213 -0
- data/test/unit/view.rb +431 -0
- data/test/unit/widgets.rb +669 -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 +1420 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +1378 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +190 -0
- data/ui/web/app/views/asset_management.erb +589 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +162 -0
- data/ui/web/app/views/deploy_config.erb +146 -0
- data/ui/web/app/views/edit_pages.erb +195 -0
- data/ui/web/app/views/edit_post.erb +54 -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/view_dashboard.erb +138 -0
- data/ui/web/bin/scriptorium-web +153 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/web_server.log +5 -0
- data/ui/web/tmp/web_server.pid +1 -0
- metadata +360 -5
@@ -0,0 +1,192 @@
|
|
1
|
+
# Set up environment for banner tests
|
2
|
+
ENV['PATH'] = "#{ENV['HOME']}/.rbenv/shims:#{ENV['PATH']}"
|
3
|
+
|
4
|
+
# Minimal environment for banner tests
|
5
|
+
require 'fileutils'
|
6
|
+
require 'find'
|
7
|
+
|
8
|
+
# Create test directory if it doesn't exist
|
9
|
+
test_dir = File.dirname(__FILE__)/"banner-tests"
|
10
|
+
FileUtils.rm_rf(test_dir) if Dir.exist?(test_dir)
|
11
|
+
Dir.mkdir(test_dir)
|
12
|
+
|
13
|
+
@pid = nil
|
14
|
+
# Start server from the project root directory
|
15
|
+
server_dir = File.expand_path("../..", __FILE__)
|
16
|
+
Dir.chdir(server_dir) do
|
17
|
+
Process.spawn ("ruby -run -e httpd . -p 8000 >/dev/null 2>&1")
|
18
|
+
sleep 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def instruct(msg)
|
22
|
+
lines = msg.split("\n")
|
23
|
+
longest = lines.map {|line| line.length }.max
|
24
|
+
puts " +" + "-" * (longest + 4) + "+"
|
25
|
+
lines.each do |line|
|
26
|
+
puts " | #{line.ljust(longest + 2)} |"
|
27
|
+
end
|
28
|
+
puts " +" + "-" * (longest + 4) + "+"
|
29
|
+
puts
|
30
|
+
end
|
31
|
+
|
32
|
+
def examine(view_name)
|
33
|
+
index_url = "http://127.0.0.1:8000/manual/banner-tests/index.html"
|
34
|
+
|
35
|
+
if ARGV.include?('--automated')
|
36
|
+
# Basic validation for automated mode
|
37
|
+
index_file = File.dirname(__FILE__)/"banner-tests/index.html"
|
38
|
+
if File.exist?(index_file)
|
39
|
+
content = File.read(index_file)
|
40
|
+
test_count = content.scan(/<div class='test-item'>/).count
|
41
|
+
|
42
|
+
# Check that at least one test file has custom content
|
43
|
+
test_file = File.dirname(__FILE__)/"banner-tests/test04.html" # Red to Blue gradient test
|
44
|
+
if File.exist?(test_file)
|
45
|
+
test_content = File.read(test_file)
|
46
|
+
unless test_content.include?('linearGradient') || test_content.include?('radialGradient') || test_content.include?('fill=\'#ff0000\'')
|
47
|
+
puts "⚠ Warning: No custom banner content found"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
else
|
51
|
+
puts "✗ Error: Index file not generated"
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Press Enter to open the generated front page to inspect the result."
|
59
|
+
STDIN.gets
|
60
|
+
system("open #{index_url}")
|
61
|
+
|
62
|
+
puts "Press Enter to kill webrick"
|
63
|
+
STDIN.gets
|
64
|
+
line = `ps | grep "ruby -run -e httpd" | grep -v grep`
|
65
|
+
pid = line.split.first
|
66
|
+
pid2 = pid.to_i + 1
|
67
|
+
system("kill #{pid} #{pid2}")
|
68
|
+
end
|
69
|
+
|
70
|
+
# Simple post creation for banner tests
|
71
|
+
def create_banner_post(title, subtitle, config_content, description, view_name, post_num = nil)
|
72
|
+
# Write config file FIRST, before creating banner
|
73
|
+
File.write("banner-tests/config.txt", config_content)
|
74
|
+
|
75
|
+
# Create banner AFTER config is written, in the correct directory
|
76
|
+
# Load the main Scriptorium library
|
77
|
+
require_relative '../../lib/scriptorium'
|
78
|
+
|
79
|
+
# Change to the test directory so the banner can find config.txt
|
80
|
+
Dir.chdir("banner-tests") do
|
81
|
+
banner = Scriptorium::BannerSVG.new(title, subtitle)
|
82
|
+
|
83
|
+
# Parse config first to set instance variables
|
84
|
+
banner.parse_header_svg
|
85
|
+
|
86
|
+
# Generate static SVG for manual inspection
|
87
|
+
# First parse config to set instance variables, then generate SVG
|
88
|
+
banner.parse_header_svg
|
89
|
+
svg_output = banner.generate_svg
|
90
|
+
|
91
|
+
# Use provided post_num or generate one
|
92
|
+
Dir.mkdir("posts") unless Dir.exist?("posts")
|
93
|
+
post_num ||= Dir.glob("posts/*").length + 1
|
94
|
+
post_dir = "posts/#{post_num.to_s.rjust(4, '0')}"
|
95
|
+
Dir.mkdir(post_dir) unless Dir.exist?(post_dir)
|
96
|
+
|
97
|
+
# Create individual page with banner at the top
|
98
|
+
post_html = <<~HTML
|
99
|
+
<!DOCTYPE html>
|
100
|
+
<html>
|
101
|
+
<head>
|
102
|
+
<title>#{title}</title>
|
103
|
+
<style>
|
104
|
+
body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
|
105
|
+
.banner { width: 100%; margin: 0; padding: 0; }
|
106
|
+
.content { padding: 20px; }
|
107
|
+
.description { margin: 10px 0; font-weight: bold; }
|
108
|
+
.config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
|
109
|
+
.navigation { background: #e0e0e0; padding: 10px; margin: 20px 0; text-align: center; }
|
110
|
+
.navigation a { margin: 0 10px; padding: 5px 10px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
|
111
|
+
.navigation a:hover { background: #005a87; }
|
112
|
+
</style>
|
113
|
+
</head>
|
114
|
+
<body>
|
115
|
+
#{svg_output}
|
116
|
+
<div class="content">
|
117
|
+
<h1>#{title}</h1>
|
118
|
+
<div class="description">#{description}</div>
|
119
|
+
<div class="config">#{config_content}</div>
|
120
|
+
<div class="navigation">
|
121
|
+
<a href="../index.html">Back to Index</a>
|
122
|
+
</div>
|
123
|
+
</div>
|
124
|
+
</body>
|
125
|
+
</html>
|
126
|
+
HTML
|
127
|
+
|
128
|
+
# Write individual post file
|
129
|
+
File.write("#{post_dir}/index.html", post_html)
|
130
|
+
|
131
|
+
# Add to view for index generation
|
132
|
+
view_dir = "views/#{view_name}/output/posts"
|
133
|
+
FileUtils.mkdir_p(view_dir) unless Dir.exist?(view_dir)
|
134
|
+
File.write("#{view_dir}/#{post_num.to_s.rjust(4, '0')}.html", post_html)
|
135
|
+
|
136
|
+
# Return post info for navigation links
|
137
|
+
{ number: post_num, title: title, filename: "#{post_num.to_s.rjust(4, '0')}.html" }
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def generate_front_page(view_name)
|
142
|
+
# Create simple index page
|
143
|
+
posts = Dir.glob("scriptorium-TEST/views/#{view_name}/output/posts/*.html").sort
|
144
|
+
|
145
|
+
index_html = <<~HTML
|
146
|
+
<!DOCTYPE html>
|
147
|
+
<html>
|
148
|
+
<head>
|
149
|
+
<title>Banner Tests - #{view_name}</title>
|
150
|
+
<style>
|
151
|
+
body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
|
152
|
+
.post { background: white; margin: 20px 0; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
153
|
+
.banner { margin: 20px 0; border: 1px solid #ddd; background: white; }
|
154
|
+
.description { margin: 10px 0; font-weight: bold; }
|
155
|
+
.config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
|
156
|
+
</style>
|
157
|
+
</head>
|
158
|
+
<body>
|
159
|
+
<h1>Banner Tests - #{view_name}</h1>
|
160
|
+
HTML
|
161
|
+
|
162
|
+
posts.each do |post_file|
|
163
|
+
post_content = File.read(post_file)
|
164
|
+
# Extract title, banner, description, and config from post
|
165
|
+
title_match = post_content.match(/<h1>(.*?)<\/h1>/)
|
166
|
+
banner_match = post_content.match(/<div class="banner">(.*?)<\/div>/m)
|
167
|
+
desc_match = post_content.match(/<div class="description">(.*?)<\/div>/)
|
168
|
+
config_match = post_content.match(/<div class="config">(.*?)<\/div>/m)
|
169
|
+
|
170
|
+
title = title_match ? title_match[1] : "Unknown"
|
171
|
+
banner = banner_match ? banner_match[1] : ""
|
172
|
+
description = desc_match ? desc_match[1] : ""
|
173
|
+
config = config_match ? config_match[1] : ""
|
174
|
+
|
175
|
+
index_html += <<~HTML
|
176
|
+
<div class="post">
|
177
|
+
<h2>#{title}</h2>
|
178
|
+
<div class="banner">#{banner}</div>
|
179
|
+
<div class="description">#{description}</div>
|
180
|
+
<div class="config">#{config}</div>
|
181
|
+
</div>
|
182
|
+
HTML
|
183
|
+
end
|
184
|
+
|
185
|
+
index_html += <<~HTML
|
186
|
+
</body>
|
187
|
+
</html>
|
188
|
+
HTML
|
189
|
+
|
190
|
+
FileUtils.mkdir_p("scriptorium-TEST/views/#{view_name}/output")
|
191
|
+
File.write("scriptorium-TEST/views/#{view_name}/output/index.html", index_html)
|
192
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Manual test script to demonstrate deployment with symlinks
|
4
|
+
# Run with: ruby test/manual/deploy_symlink_demo.rb
|
5
|
+
|
6
|
+
require_relative '../../lib/scriptorium'
|
7
|
+
require_relative '../test_helpers'
|
8
|
+
|
9
|
+
class DeploySymlinkDemo
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
include TestHelpers
|
12
|
+
|
13
|
+
def run
|
14
|
+
puts "=== Deployment with Symlinks Demo ==="
|
15
|
+
puts
|
16
|
+
|
17
|
+
# Create test repository
|
18
|
+
puts "1. Creating test repository..."
|
19
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true)
|
20
|
+
@view = @repo.create_view("demo_view", "Demo View", "A demo view for deployment")
|
21
|
+
puts " ✓ Created repository and view"
|
22
|
+
puts
|
23
|
+
|
24
|
+
# Create a test post
|
25
|
+
puts "2. Creating test post..."
|
26
|
+
post_title = "Deployment Test Post with Symlinks"
|
27
|
+
post_body = "This post tests deployment with symlinks."
|
28
|
+
|
29
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
30
|
+
post_num = @repo.finish_draft(draft_name)
|
31
|
+
puts " ✓ Created post ##{post_num}: #{post_title}"
|
32
|
+
puts
|
33
|
+
|
34
|
+
# Generate the post
|
35
|
+
puts "3. Generating post..."
|
36
|
+
@repo.generate_post(post_num)
|
37
|
+
puts " ✓ Generated post"
|
38
|
+
puts
|
39
|
+
|
40
|
+
# Check the files
|
41
|
+
puts "4. Checking generated files..."
|
42
|
+
|
43
|
+
numbered_slug = slugify(post_num, post_title) + ".html"
|
44
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
45
|
+
|
46
|
+
numbered_path = @view.dir/:output/:permalink/numbered_slug
|
47
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
48
|
+
|
49
|
+
puts " Numbered file: #{numbered_path}"
|
50
|
+
puts " Clean symlink: #{clean_symlink_path}"
|
51
|
+
puts
|
52
|
+
|
53
|
+
# Verify files exist
|
54
|
+
if File.exist?(numbered_path)
|
55
|
+
puts " ✓ Numbered file exists"
|
56
|
+
else
|
57
|
+
puts " ✗ Numbered file missing"
|
58
|
+
end
|
59
|
+
|
60
|
+
if File.exist?(clean_symlink_path)
|
61
|
+
puts " ✓ Clean symlink exists"
|
62
|
+
else
|
63
|
+
puts " ✗ Clean symlink missing"
|
64
|
+
end
|
65
|
+
|
66
|
+
if File.symlink?(clean_symlink_path)
|
67
|
+
puts " ✓ Clean symlink is actually a symlink"
|
68
|
+
symlink_target = File.readlink(clean_symlink_path)
|
69
|
+
puts " ✓ Symlink points to: #{symlink_target}"
|
70
|
+
else
|
71
|
+
puts " ✗ Clean symlink is not a symlink"
|
72
|
+
end
|
73
|
+
puts
|
74
|
+
|
75
|
+
# Test deployment simulation
|
76
|
+
puts "5. Testing deployment simulation..."
|
77
|
+
|
78
|
+
# Create a test deployment directory
|
79
|
+
test_deploy_dir = "test/deploy-test"
|
80
|
+
FileUtils.rm_rf(test_deploy_dir) if Dir.exist?(test_deploy_dir)
|
81
|
+
FileUtils.mkdir_p(test_deploy_dir)
|
82
|
+
|
83
|
+
# Simulate rsync command with symlink preservation
|
84
|
+
output_dir = @view.dir/:output
|
85
|
+
rsync_cmd = "rsync -r -z -l #{output_dir}/ #{test_deploy_dir}/"
|
86
|
+
puts " Simulating: #{rsync_cmd}"
|
87
|
+
|
88
|
+
# Actually copy files (simulating rsync)
|
89
|
+
FileUtils.cp_r("#{output_dir}/.", test_deploy_dir)
|
90
|
+
|
91
|
+
# Check if symlinks were preserved
|
92
|
+
deployed_symlink = "#{test_deploy_dir}/permalink/#{clean_slug}"
|
93
|
+
deployed_target = "#{test_deploy_dir}/permalink/#{numbered_slug}"
|
94
|
+
|
95
|
+
if File.exist?(deployed_symlink)
|
96
|
+
puts " ✓ Symlink exists in deployment directory"
|
97
|
+
|
98
|
+
if File.symlink?(deployed_symlink)
|
99
|
+
puts " ✓ Symlink is preserved in deployment"
|
100
|
+
deployed_target_readlink = File.readlink(deployed_symlink)
|
101
|
+
puts " ✓ Deployed symlink points to: #{deployed_target_readlink}"
|
102
|
+
|
103
|
+
if File.exist?(deployed_target)
|
104
|
+
puts " ✓ Symlink target exists in deployment"
|
105
|
+
else
|
106
|
+
puts " ✗ Symlink target missing in deployment"
|
107
|
+
end
|
108
|
+
else
|
109
|
+
puts " ✗ Symlink was not preserved (copied as file)"
|
110
|
+
end
|
111
|
+
else
|
112
|
+
puts " ✗ Symlink missing in deployment directory"
|
113
|
+
end
|
114
|
+
puts
|
115
|
+
|
116
|
+
# Show deployment structure
|
117
|
+
puts "6. Deployment directory structure:"
|
118
|
+
if Dir.exist?(test_deploy_dir)
|
119
|
+
Dir.glob("#{test_deploy_dir}/**/*").sort.each do |file|
|
120
|
+
relative_path = file.sub("#{test_deploy_dir}/", "")
|
121
|
+
if File.symlink?(file)
|
122
|
+
target = File.readlink(file)
|
123
|
+
puts " #{relative_path} -> #{target} (symlink)"
|
124
|
+
elsif File.directory?(file)
|
125
|
+
puts " #{relative_path}/ (directory)"
|
126
|
+
else
|
127
|
+
puts " #{relative_path} (file)"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
puts
|
132
|
+
|
133
|
+
puts "=== Demo Complete ==="
|
134
|
+
puts
|
135
|
+
puts "To clean up, run: rm -rf test/scriptorium-TEST test/deploy-test"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
if __FILE__ == $0
|
140
|
+
demo = DeploySymlinkDemo.new
|
141
|
+
demo.run
|
142
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Set up environment for manual tests
|
2
|
+
ENV['PATH'] = "#{ENV['HOME']}/.rbenv/shims:#{ENV['PATH']}"
|
3
|
+
|
4
|
+
# rbenv should be enabled in the shell before running manual tests
|
5
|
+
|
6
|
+
require_relative '../../lib/scriptorium'
|
7
|
+
require_relative '../test_helpers'
|
8
|
+
|
9
|
+
include TestHelpers
|
10
|
+
|
11
|
+
def manual_setup
|
12
|
+
system("rm -rf test/scriptorium-TEST")
|
13
|
+
|
14
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true) # true for testing mode
|
15
|
+
|
16
|
+
@pid = nil
|
17
|
+
Dir.chdir(File.expand_path("..", __dir__)) do
|
18
|
+
Process.spawn ("ruby -run -e httpd . -p 8000 >/dev/null 2>&1")
|
19
|
+
sleep 1
|
20
|
+
puts "webrick started\n "
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def instruct(msg)
|
25
|
+
lines = msg.split("\n")
|
26
|
+
longest = lines.map {|line| line.length }.max
|
27
|
+
puts " +" + "-" * (longest + 4) + "+"
|
28
|
+
lines.each do |line|
|
29
|
+
puts " | #{line.ljust(longest + 2)} |"
|
30
|
+
end
|
31
|
+
puts " +" + "-" * (longest + 4) + "+"
|
32
|
+
puts
|
33
|
+
end
|
34
|
+
|
35
|
+
def examine(view)
|
36
|
+
view = @repo.lookup_view(view)
|
37
|
+
index_url = "http://127.0.0.1:8000/scriptorium-TEST/views/#{view.name}/output/index.html"
|
38
|
+
puts "Generated front page located at: \n#{index_url}"
|
39
|
+
|
40
|
+
if ARGV.include?('--automated')
|
41
|
+
# Automated mode - just validate files were created
|
42
|
+
index_file = "test/scriptorium-TEST/views/#{view.name}/output/index.html"
|
43
|
+
if File.exist?(index_file)
|
44
|
+
puts "✓ Files generated successfully"
|
45
|
+
else
|
46
|
+
puts "✗ Error: Index file not generated"
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
puts "Press Enter to open the generated front page to inspect the result."
|
53
|
+
STDIN.gets
|
54
|
+
cmd = "open #{index_url}"
|
55
|
+
see("cmd = ", cmd)
|
56
|
+
system("open #{index_url}")
|
57
|
+
|
58
|
+
puts "Press Enter to kill webrick"
|
59
|
+
STDIN.gets
|
60
|
+
line = `ps | grep "ruby -run -e httpd" | grep -v grep`
|
61
|
+
pid = line.split.first
|
62
|
+
puts "line: #{line}"
|
63
|
+
puts "pid: #{pid}"
|
64
|
+
pid2 = pid.to_i + 1
|
65
|
+
system("kill #{pid} #{pid2}")
|
66
|
+
puts "Killed\n "
|
67
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../../lib/scriptorium'
|
4
|
+
include Scriptorium::Helpers
|
5
|
+
|
6
|
+
# Simple banner test from configuration file
|
7
|
+
def test_banner_from_file(config_file, title = nil, subtitle = nil, output_file = nil)
|
8
|
+
# Default output file if not specified
|
9
|
+
output_file ||= "banner_output.html"
|
10
|
+
|
11
|
+
# Default titles if not specified
|
12
|
+
title ||= "Test Banner"
|
13
|
+
subtitle ||= "Generated from config file"
|
14
|
+
|
15
|
+
# Read the configuration file
|
16
|
+
unless File.exist?(config_file)
|
17
|
+
puts "Error: Configuration file '#{config_file}' not found"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
# Use the read_commented_file helper to read the config
|
22
|
+
config_lines = read_commented_file(config_file)
|
23
|
+
config_content = File.read(config_file) # Keep original for display
|
24
|
+
|
25
|
+
puts "Read configuration from: #{config_file}"
|
26
|
+
puts "Found #{config_lines.length} configuration lines (comments removed)"
|
27
|
+
puts "Title: #{title}"
|
28
|
+
puts "Subtitle: #{subtitle}"
|
29
|
+
|
30
|
+
# Create banner with the actual titles from View
|
31
|
+
banner = Scriptorium::BannerSVG.new(title, subtitle)
|
32
|
+
|
33
|
+
# Write config to temporary file for banner to read
|
34
|
+
temp_config = "config.txt"
|
35
|
+
File.write(temp_config, config_content)
|
36
|
+
|
37
|
+
# Parse and generate the banner
|
38
|
+
banner.parse_header_svg
|
39
|
+
svg_output = banner.generate_svg
|
40
|
+
|
41
|
+
# Clean up temp config file
|
42
|
+
File.delete(temp_config) if File.exist?(temp_config)
|
43
|
+
|
44
|
+
# Create HTML output
|
45
|
+
html_content = <<~HTML
|
46
|
+
<!DOCTYPE html>
|
47
|
+
<html>
|
48
|
+
<head>
|
49
|
+
<title>Banner Test - #{File.basename(config_file)}</title>
|
50
|
+
<style>
|
51
|
+
body {
|
52
|
+
font-family: Arial, sans-serif;
|
53
|
+
margin: 0;
|
54
|
+
padding: 20px;
|
55
|
+
background: #f5f5f5;
|
56
|
+
}
|
57
|
+
.banner {
|
58
|
+
width: 100%;
|
59
|
+
max-width: 800px;
|
60
|
+
margin: 0 auto 20px auto;
|
61
|
+
border: 2px solid #007cba;
|
62
|
+
border-radius: 8px;
|
63
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
64
|
+
}
|
65
|
+
.config {
|
66
|
+
background: white;
|
67
|
+
padding: 20px;
|
68
|
+
margin: 20px auto;
|
69
|
+
max-width: 800px;
|
70
|
+
border-radius: 8px;
|
71
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
72
|
+
}
|
73
|
+
.config h3 {
|
74
|
+
margin-top: 0;
|
75
|
+
color: #333;
|
76
|
+
}
|
77
|
+
.config pre {
|
78
|
+
background: #f8f9fa;
|
79
|
+
padding: 15px;
|
80
|
+
border-radius: 4px;
|
81
|
+
overflow-x: auto;
|
82
|
+
font-family: monospace;
|
83
|
+
font-size: 12px;
|
84
|
+
}
|
85
|
+
.info {
|
86
|
+
background: white;
|
87
|
+
padding: 20px;
|
88
|
+
margin: 20px auto;
|
89
|
+
max-width: 800px;
|
90
|
+
border-radius: 8px;
|
91
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
92
|
+
}
|
93
|
+
.processed-config {
|
94
|
+
background: #e8f4fd;
|
95
|
+
padding: 15px;
|
96
|
+
margin: 10px 0;
|
97
|
+
border-radius: 4px;
|
98
|
+
font-family: monospace;
|
99
|
+
font-size: 12px;
|
100
|
+
}
|
101
|
+
</style>
|
102
|
+
</head>
|
103
|
+
<body>
|
104
|
+
<div class="banner">
|
105
|
+
#{svg_output}
|
106
|
+
</div>
|
107
|
+
|
108
|
+
<div class="info">
|
109
|
+
<h3>Banner Information</h3>
|
110
|
+
<p><strong>Configuration file:</strong> #{config_file}</p>
|
111
|
+
<p><strong>Output file:</strong> #{output_file}</p>
|
112
|
+
<p><strong>Generated:</strong> #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}</p>
|
113
|
+
<p><strong>Configuration lines processed:</strong> #{config_lines.length}</p>
|
114
|
+
</div>
|
115
|
+
|
116
|
+
<div class="config">
|
117
|
+
<h3>Configuration Used </h3>
|
118
|
+
<pre>#{config_content}</pre>
|
119
|
+
</div>
|
120
|
+
</body>
|
121
|
+
</html>
|
122
|
+
HTML
|
123
|
+
|
124
|
+
# Write the HTML file
|
125
|
+
File.write(output_file, html_content)
|
126
|
+
puts "Generated banner HTML: #{output_file}"
|
127
|
+
|
128
|
+
# Open in browser if on macOS
|
129
|
+
if RUBY_PLATFORM.include?('darwin')
|
130
|
+
puts "Opening in browser..."
|
131
|
+
system("open #{output_file}")
|
132
|
+
else
|
133
|
+
puts "Open #{output_file} in your browser to view the banner"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Main execution
|
138
|
+
if ARGV.empty?
|
139
|
+
puts "Usage: ruby make_banner.rb <config_file> [title] [subtitle] [output_file]"
|
140
|
+
puts ""
|
141
|
+
puts "Example:"
|
142
|
+
puts " ruby make_banner.rb my_banner_config.txt"
|
143
|
+
puts " ruby make_banner.rb my_banner_config.txt 'My Blog' 'A subtitle'"
|
144
|
+
puts " ruby make_banner.rb my_banner_config.txt 'My Blog' 'A subtitle' custom_output.html"
|
145
|
+
exit 1
|
146
|
+
end
|
147
|
+
|
148
|
+
config_file = ARGV[0]
|
149
|
+
title = ARGV[1] # Optional
|
150
|
+
subtitle = ARGV[2] # Optional
|
151
|
+
output_file = ARGV[3] # Optional
|
152
|
+
|
153
|
+
test_banner_from_file(config_file, title, subtitle, output_file)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
aspect 7.0 # Aspect ratio (width:height)
|
2
|
+
text.font verdana # For both title and subtitle
|
3
|
+
text.color #cccccc
|
4
|
+
text.justify left # For both title and subtitle
|
5
|
+
|
6
|
+
title.scale 0.8 # ~48px (1.5x <h1>)
|
7
|
+
subtitle.scale 0.4 # 24px ~= <h2>
|
8
|
+
|
9
|
+
title.style bold # boldfaced title
|
10
|
+
subtitle.style bold italic # bold *and* italic (actually uses SVG weight and style)
|
11
|
+
title.xy 5 10
|
12
|
+
subtitle.xy 5 40
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Manual test script to demonstrate symlink functionality
|
4
|
+
# Run with: ruby test/manual/symlink_demo.rb
|
5
|
+
|
6
|
+
require_relative '../../lib/scriptorium'
|
7
|
+
require_relative '../test_helpers'
|
8
|
+
|
9
|
+
class SymlinkDemo
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
include TestHelpers
|
12
|
+
|
13
|
+
def run
|
14
|
+
puts "=== Symlink Functionality Demo ==="
|
15
|
+
puts
|
16
|
+
|
17
|
+
# Create test repository
|
18
|
+
puts "1. Creating test repository..."
|
19
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true)
|
20
|
+
@view = @repo.create_view("demo_view", "Demo View", "A demo view for symlinks")
|
21
|
+
puts " ✓ Created repository and view"
|
22
|
+
puts
|
23
|
+
|
24
|
+
# Create a test post
|
25
|
+
puts "2. Creating test post..."
|
26
|
+
post_title = "My First Test Post with Special Characters: & < > \" ' !"
|
27
|
+
post_body = "This is the body of my test post. It contains some content."
|
28
|
+
|
29
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
30
|
+
post_num = @repo.finish_draft(draft_name)
|
31
|
+
puts " ✓ Created post ##{post_num}: #{post_title}"
|
32
|
+
puts
|
33
|
+
|
34
|
+
# Generate the post
|
35
|
+
puts "3. Generating post..."
|
36
|
+
@repo.generate_post(post_num)
|
37
|
+
puts " ✓ Generated post"
|
38
|
+
puts
|
39
|
+
|
40
|
+
# Check the files
|
41
|
+
puts "4. Checking generated files..."
|
42
|
+
|
43
|
+
numbered_slug = slugify(post_num, post_title) + ".html"
|
44
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
45
|
+
|
46
|
+
numbered_path = @view.dir/:output/:permalink/numbered_slug
|
47
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
48
|
+
|
49
|
+
puts " Numbered file: #{numbered_path}"
|
50
|
+
puts " Clean symlink: #{clean_symlink_path}"
|
51
|
+
puts
|
52
|
+
|
53
|
+
# Verify files exist
|
54
|
+
if File.exist?(numbered_path)
|
55
|
+
puts " ✓ Numbered file exists"
|
56
|
+
else
|
57
|
+
puts " ✗ Numbered file missing"
|
58
|
+
end
|
59
|
+
|
60
|
+
if File.exist?(clean_symlink_path)
|
61
|
+
puts " ✓ Clean symlink exists"
|
62
|
+
else
|
63
|
+
puts " ✗ Clean symlink missing"
|
64
|
+
end
|
65
|
+
|
66
|
+
if File.symlink?(clean_symlink_path)
|
67
|
+
puts " ✓ Clean symlink is actually a symlink"
|
68
|
+
symlink_target = File.readlink(clean_symlink_path)
|
69
|
+
puts " ✓ Symlink points to: #{symlink_target}"
|
70
|
+
else
|
71
|
+
puts " ✗ Clean symlink is not a symlink"
|
72
|
+
end
|
73
|
+
puts
|
74
|
+
|
75
|
+
# Show the URLs
|
76
|
+
puts "5. Generated URLs:"
|
77
|
+
puts " Numbered URL: /permalink/#{numbered_slug}"
|
78
|
+
puts " Clean URL: /permalink/#{clean_slug}"
|
79
|
+
puts
|
80
|
+
|
81
|
+
# Test the symlink
|
82
|
+
puts "6. Testing symlink..."
|
83
|
+
if File.symlink?(clean_symlink_path)
|
84
|
+
symlink_target = File.readlink(clean_symlink_path)
|
85
|
+
if symlink_target == numbered_slug
|
86
|
+
puts " ✓ Symlink correctly points to numbered file"
|
87
|
+
else
|
88
|
+
puts " ✗ Symlink points to wrong target: #{symlink_target}"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
puts " ✗ Clean symlink is not a symlink"
|
92
|
+
end
|
93
|
+
puts
|
94
|
+
|
95
|
+
# Show file contents
|
96
|
+
puts "7. File contents:"
|
97
|
+
if File.exist?(numbered_path)
|
98
|
+
content = File.read(numbered_path)
|
99
|
+
puts " Numbered file size: #{content.length} bytes"
|
100
|
+
puts " Contains 'Back to Blog' link: #{content.include?('Back to Blog') ? 'Yes' : 'No'}"
|
101
|
+
end
|
102
|
+
|
103
|
+
if File.exist?(clean_symlink_path) && File.symlink?(clean_symlink_path)
|
104
|
+
puts " Clean symlink: points to #{File.readlink(clean_symlink_path)}"
|
105
|
+
end
|
106
|
+
puts
|
107
|
+
|
108
|
+
puts "=== Demo Complete ==="
|
109
|
+
puts
|
110
|
+
puts "To clean up, run: rm -rf test/scriptorium-TEST"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if __FILE__ == $0
|
115
|
+
demo = SymlinkDemo.new
|
116
|
+
demo.run
|
117
|
+
end
|