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,150 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../../lib/scriptorium'
|
4
|
+
|
5
|
+
include Scriptorium::Helpers
|
6
|
+
|
7
|
+
# Simple banner test from configuration file
|
8
|
+
def test_banner_from_file(config_file, output_file = nil)
|
9
|
+
# Default output file if not specified
|
10
|
+
output_file ||= "banner_output.html"
|
11
|
+
|
12
|
+
# Read the configuration file
|
13
|
+
unless File.exist?(config_file)
|
14
|
+
puts "Error: Configuration file '#{config_file}' not found"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
# Use the read_commented_file helper to read the config
|
19
|
+
config_lines = read_commented_file(config_file)
|
20
|
+
config_content = File.read(config_file) # Keep original for display
|
21
|
+
|
22
|
+
puts "Read configuration from: #{config_file}"
|
23
|
+
puts "Found #{config_lines.length} configuration lines (comments removed)"
|
24
|
+
|
25
|
+
# Create banner with default title/subtitle
|
26
|
+
banner = Scriptorium::BannerSVG.new("Test Banner", "Generated from config file")
|
27
|
+
|
28
|
+
# Write config to temporary file for banner to read
|
29
|
+
temp_config = "temp_banner_config.txt"
|
30
|
+
File.write(temp_config, config_content)
|
31
|
+
|
32
|
+
# Parse and generate the banner
|
33
|
+
banner.parse_header_svg
|
34
|
+
svg_output = banner.generate_svg
|
35
|
+
|
36
|
+
# Clean up temp config file
|
37
|
+
File.delete(temp_config) if File.exist?(temp_config)
|
38
|
+
|
39
|
+
# Create HTML output
|
40
|
+
html_content = <<~HTML
|
41
|
+
<!DOCTYPE html>
|
42
|
+
<html>
|
43
|
+
<head>
|
44
|
+
<title>Banner Test - #{File.basename(config_file)}</title>
|
45
|
+
<style>
|
46
|
+
body {
|
47
|
+
font-family: Arial, sans-serif;
|
48
|
+
margin: 0;
|
49
|
+
padding: 20px;
|
50
|
+
background: #f5f5f5;
|
51
|
+
}
|
52
|
+
.banner {
|
53
|
+
width: 100%;
|
54
|
+
max-width: 800px;
|
55
|
+
margin: 0 auto 20px auto;
|
56
|
+
border: 2px solid #007cba;
|
57
|
+
border-radius: 8px;
|
58
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
59
|
+
}
|
60
|
+
.config {
|
61
|
+
background: white;
|
62
|
+
padding: 20px;
|
63
|
+
margin: 20px auto;
|
64
|
+
max-width: 800px;
|
65
|
+
border-radius: 8px;
|
66
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
67
|
+
}
|
68
|
+
.config h3 {
|
69
|
+
margin-top: 0;
|
70
|
+
color: #333;
|
71
|
+
}
|
72
|
+
.config pre {
|
73
|
+
background: #f8f9fa;
|
74
|
+
padding: 15px;
|
75
|
+
border-radius: 4px;
|
76
|
+
overflow-x: auto;
|
77
|
+
font-family: monospace;
|
78
|
+
font-size: 12px;
|
79
|
+
}
|
80
|
+
.info {
|
81
|
+
background: white;
|
82
|
+
padding: 20px;
|
83
|
+
margin: 20px auto;
|
84
|
+
max-width: 800px;
|
85
|
+
border-radius: 8px;
|
86
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
87
|
+
}
|
88
|
+
.processed-config {
|
89
|
+
background: #e8f4fd;
|
90
|
+
padding: 15px;
|
91
|
+
margin: 10px 0;
|
92
|
+
border-radius: 4px;
|
93
|
+
font-family: monospace;
|
94
|
+
font-size: 12px;
|
95
|
+
}
|
96
|
+
</style>
|
97
|
+
</head>
|
98
|
+
<body>
|
99
|
+
<div class="banner">
|
100
|
+
#{svg_output}
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<div class="info">
|
104
|
+
<h3>Banner Information</h3>
|
105
|
+
<p><strong>Configuration file:</strong> #{config_file}</p>
|
106
|
+
<p><strong>Output file:</strong> #{output_file}</p>
|
107
|
+
<p><strong>Generated:</strong> #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}</p>
|
108
|
+
<p><strong>Configuration lines processed:</strong> #{config_lines.length}</p>
|
109
|
+
</div>
|
110
|
+
|
111
|
+
<div class="config">
|
112
|
+
<h3>Configuration Used (with comments)</h3>
|
113
|
+
<pre>#{config_content}</pre>
|
114
|
+
|
115
|
+
<h3>Processed Configuration (comments removed)</h3>
|
116
|
+
<div class="processed-config">
|
117
|
+
#{config_lines.map { |line| line.empty? ? "# (empty line)" : line }.join("\n")}
|
118
|
+
</div>
|
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 test_banner_from_file.rb <config_file> [output_file]"
|
140
|
+
puts ""
|
141
|
+
puts "Example:"
|
142
|
+
puts " ruby test_banner_from_file.rb my_banner_config.txt"
|
143
|
+
puts " ruby test_banner_from_file.rb my_banner_config.txt custom_output.html"
|
144
|
+
exit 1
|
145
|
+
end
|
146
|
+
|
147
|
+
config_file = ARGV[0]
|
148
|
+
output_file = ARGV[1] # Optional
|
149
|
+
|
150
|
+
test_banner_from_file(config_file, output_file)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a simple view
|
6
|
+
view = @repo.create_view("banner-test", "My Banner Site", "A site with SVG banner in header")
|
7
|
+
|
8
|
+
# Set up layout with header
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
f.puts "main"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Generate the empty containers
|
15
|
+
view.generate_empty_containers
|
16
|
+
|
17
|
+
# Configure the header to include the SVG banner
|
18
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
19
|
+
f.puts "banner svg"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Generate the front page
|
23
|
+
view.generate_front_page
|
24
|
+
|
25
|
+
instruct <<~EOS
|
26
|
+
This test shows how to insert an SVG banner into the header.
|
27
|
+
|
28
|
+
The header.txt contains:
|
29
|
+
- banner svg (inserts the SVG banner)
|
30
|
+
|
31
|
+
The SVG banner will appear at the top of the header.
|
32
|
+
The banner automatically uses the view's title and subtitle as its content.
|
33
|
+
EOS
|
34
|
+
|
35
|
+
examine view
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative "./environment"
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
@repo.create_view("testview", "Test View", "A test view for manual inspection")
|
6
|
+
|
7
|
+
# Post with code highlighting
|
8
|
+
draft_body = <<~BODY
|
9
|
+
.blurb Testing code highlighting with Prism.
|
10
|
+
This post tests the .code function and Prism syntax highlighting.
|
11
|
+
|
12
|
+
Here's some Ruby code:
|
13
|
+
|
14
|
+
.code ruby
|
15
|
+
def hello_world
|
16
|
+
puts "Hello, World!"
|
17
|
+
@greeting = "Welcome to Scriptorium"
|
18
|
+
return @greeting
|
19
|
+
end
|
20
|
+
.end
|
21
|
+
|
22
|
+
And some JavaScript:
|
23
|
+
|
24
|
+
.code javascript
|
25
|
+
function greet(name) {
|
26
|
+
console.log("Hello, " + name);
|
27
|
+
return "Greeting sent";
|
28
|
+
}
|
29
|
+
.end
|
30
|
+
|
31
|
+
And plain text:
|
32
|
+
|
33
|
+
.code text
|
34
|
+
This is just plain text
|
35
|
+
No syntax highlighting needed
|
36
|
+
But it should still be in a code block
|
37
|
+
.end
|
38
|
+
|
39
|
+
And some more Ruby:
|
40
|
+
|
41
|
+
.code ruby
|
42
|
+
class Example
|
43
|
+
def initialize
|
44
|
+
@data = []
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_item(item)
|
48
|
+
@data << item
|
49
|
+
end
|
50
|
+
end
|
51
|
+
.end
|
52
|
+
BODY
|
53
|
+
|
54
|
+
name = @repo.create_draft(title: "Code Highlighting Test", views: ["testview"], body: draft_body)
|
55
|
+
num = @repo.finish_draft(name)
|
56
|
+
@repo.generate_post(num)
|
57
|
+
|
58
|
+
@repo.generate_front_page("testview")
|
59
|
+
|
60
|
+
instruct <<~EOS
|
61
|
+
Front page should have one post with code highlighting.
|
62
|
+
Ruby code should be highlighted with Ruby syntax.
|
63
|
+
JavaScript code should be highlighted with JS syntax.
|
64
|
+
Plain text should be in code blocks but not highlighted.
|
65
|
+
Check that Prism CSS and JS are included in the generated HTML.
|
66
|
+
EOS
|
67
|
+
|
68
|
+
examine("testview")
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a view with a complex header
|
6
|
+
view = @repo.create_view("complex-header", "My Awesome Blog", "Exploring the Power of SVG Banners")
|
7
|
+
|
8
|
+
# Set up layout with header
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
f.puts "main"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Generate the empty containers
|
15
|
+
view.generate_empty_containers
|
16
|
+
|
17
|
+
# Create a complex SVG banner configuration
|
18
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
19
|
+
f.puts "banner_svg"
|
20
|
+
f.puts "title"
|
21
|
+
f.puts "subtitle"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create a complex SVG banner config file
|
25
|
+
File.open(view.dir/:config/"config.txt", "w") do |f|
|
26
|
+
f.puts "# Complex SVG Banner Configuration"
|
27
|
+
f.puts "# This exercises multiple features at once"
|
28
|
+
f.puts ""
|
29
|
+
f.puts "# Background: Radial gradient from purple to blue"
|
30
|
+
f.puts "back.radial #8B5CF6 #3B82F6"
|
31
|
+
f.puts ""
|
32
|
+
f.puts "# Custom aspect ratio (wider banner)"
|
33
|
+
f.puts "aspect 6.0"
|
34
|
+
f.puts ""
|
35
|
+
f.puts "# Custom font"
|
36
|
+
f.puts "text.font Georgia serif"
|
37
|
+
f.puts ""
|
38
|
+
f.puts "# Title styling: Bold, larger scale, custom color"
|
39
|
+
f.puts "title.scale 1.2"
|
40
|
+
f.puts "title.style bold"
|
41
|
+
f.puts "title.color #FFFFFF"
|
42
|
+
f.puts "title.align center"
|
43
|
+
f.puts ""
|
44
|
+
f.puts "# Subtitle styling: Italic, smaller scale, different color"
|
45
|
+
f.puts "subtitle.scale 0.6"
|
46
|
+
f.puts "subtitle.style italic"
|
47
|
+
f.puts "subtitle.color #E5E7EB"
|
48
|
+
f.puts "subtitle.align center"
|
49
|
+
f.puts ""
|
50
|
+
f.puts "# Custom positioning for both title and subtitle"
|
51
|
+
f.puts "title.xy 50% 45%"
|
52
|
+
f.puts "subtitle.xy 50% 75%"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate the front page
|
56
|
+
view.generate_front_page
|
57
|
+
|
58
|
+
instruct <<~EOS
|
59
|
+
Complex Header Test - Multiple SVG Banner Features
|
60
|
+
|
61
|
+
This header demonstrates:
|
62
|
+
- Radial gradient background (purple to blue)
|
63
|
+
- Custom aspect ratio (6:1 - wider banner)
|
64
|
+
- Georgia serif font
|
65
|
+
- Title: Bold, larger scale (1.2x), white color, centered
|
66
|
+
- Subtitle: Italic, smaller scale (0.6x), light gray color, centered
|
67
|
+
- Custom positioning for both title and subtitle
|
68
|
+
- Responsive SVG that scales with window width
|
69
|
+
|
70
|
+
The banner should look sophisticated with the gradient background
|
71
|
+
and well-positioned, styled text elements.
|
72
|
+
EOS
|
73
|
+
|
74
|
+
examine view
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a view with an empty header
|
6
|
+
view = @repo.create_view("empty-header-test", "Empty Header Test", "Testing placeholder text")
|
7
|
+
|
8
|
+
# Set up layout with header
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
f.puts "main"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Generate the empty containers
|
15
|
+
view.generate_empty_containers
|
16
|
+
|
17
|
+
# Leave header.txt empty (no content)
|
18
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
19
|
+
# Empty file - should trigger placeholder
|
20
|
+
end
|
21
|
+
|
22
|
+
# Generate the front page
|
23
|
+
view.generate_front_page
|
24
|
+
|
25
|
+
instruct <<~EOS
|
26
|
+
This test verifies that placeholder text appears when header has no content.
|
27
|
+
|
28
|
+
The header.txt is empty, so it should show "This is header..." as placeholder text.
|
29
|
+
This confirms that our fix only removes placeholders when there's real content.
|
30
|
+
EOS
|
31
|
+
|
32
|
+
examine view
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a view with custom radial gradient
|
6
|
+
view = @repo.create_view("radial-custom", "Custom Radial Test", "Testing custom radial gradient parameters")
|
7
|
+
|
8
|
+
# Set up layout with header
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Generate the empty containers
|
14
|
+
view.generate_empty_containers
|
15
|
+
|
16
|
+
# Configure the header to only have the SVG banner
|
17
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
18
|
+
f.puts "banner_svg"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create a custom radial gradient config
|
22
|
+
File.open(view.dir/:config/"config.txt", "w") do |f|
|
23
|
+
f.puts "# Custom Radial Gradient Test"
|
24
|
+
f.puts "# Default: circular vignette (ar omitted, will use 1/aspect)"
|
25
|
+
f.puts "aspect 5.0"
|
26
|
+
f.puts "back.radial #FF6B6B #4ECDC4 75% 25% 60%"
|
27
|
+
f.puts ""
|
28
|
+
f.puts "# Custom: elliptical vignette (ar = 0.5, i.e. squished horizontally)"
|
29
|
+
f.puts "# Uncomment to test:"
|
30
|
+
f.puts "# back.radial #FF6B6B #4ECDC4 75% 25% 60% 0.5"
|
31
|
+
f.puts ""
|
32
|
+
f.puts "# Title styling"
|
33
|
+
f.puts "title.color #FFFFFF"
|
34
|
+
f.puts "title.style bold"
|
35
|
+
f.puts "title.align center"
|
36
|
+
f.puts ""
|
37
|
+
f.puts "# Subtitle styling"
|
38
|
+
f.puts "subtitle.color #FFFFFF"
|
39
|
+
f.puts "subtitle.style italic"
|
40
|
+
f.puts "subtitle.align center"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generate the front page
|
44
|
+
view.generate_front_page
|
45
|
+
|
46
|
+
instruct <<~EOS
|
47
|
+
Custom Radial Gradient Test
|
48
|
+
|
49
|
+
This test demonstrates the new aspect-ratio compensation for radial gradients:
|
50
|
+
- aspect 5.0 (wide banner)
|
51
|
+
- back.radial #FF6B6B #4ECDC4 75% 25% 60% # default: circular vignette
|
52
|
+
- Uncomment the line with ar=0.5 for an elliptical vignette
|
53
|
+
|
54
|
+
By default, the vignette should be circular even in a wide banner.
|
55
|
+
If you set ar < 1/aspect, the vignette will be squished horizontally.
|
56
|
+
EOS
|
57
|
+
|
58
|
+
examine view
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a view with a large-radius radial gradient
|
6
|
+
view = @repo.create_view("radial-large-radius", "Large Radius Radial Test", "Testing r > 100% for soft vignette")
|
7
|
+
|
8
|
+
# Set up layout with header
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Generate the empty containers
|
14
|
+
view.generate_empty_containers
|
15
|
+
|
16
|
+
# Configure the header to only have the SVG banner
|
17
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
18
|
+
f.puts "banner_svg"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create a config with a large radius
|
22
|
+
File.open(view.dir/:config/"config.txt", "w") do |f|
|
23
|
+
f.puts "# Large Radius Radial Gradient Test"
|
24
|
+
f.puts "aspect 5.0"
|
25
|
+
f.puts "# r = 150% (soft vignette, gradient extends beyond banner)"
|
26
|
+
f.puts "back.radial #FF6B6B #4ECDC4 50% 50% 150%"
|
27
|
+
f.puts ""
|
28
|
+
f.puts "# Title styling"
|
29
|
+
f.puts "title.color #FFFFFF"
|
30
|
+
f.puts "title.style bold"
|
31
|
+
f.puts "title.align center"
|
32
|
+
f.puts ""
|
33
|
+
f.puts "# Subtitle styling"
|
34
|
+
f.puts "subtitle.color #FFFFFF"
|
35
|
+
f.puts "subtitle.style italic"
|
36
|
+
f.puts "subtitle.align center"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Generate the front page
|
40
|
+
view.generate_front_page
|
41
|
+
|
42
|
+
instruct <<~EOS
|
43
|
+
Large Radius Radial Gradient Test
|
44
|
+
|
45
|
+
This test demonstrates a radial gradient with r > 100% (here, 150%).
|
46
|
+
- aspect 5.0 (wide banner)
|
47
|
+
- back.radial #FF6B6B #4ECDC4 50% 50% 150%
|
48
|
+
|
49
|
+
The gradient should be very soft, with the color fading in from outside the banner.
|
50
|
+
EOS
|
51
|
+
|
52
|
+
examine view
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative './environment'
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
# Create a simple view for debugging
|
6
|
+
view = @repo.create_view("svg-debug", "SVG Debug Test", "Testing SVG insertion")
|
7
|
+
|
8
|
+
# Set up layout with header only
|
9
|
+
File.open(view.dir/:config/"layout.txt", "w") do |f|
|
10
|
+
f.puts "header"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Generate the empty containers
|
14
|
+
view.generate_empty_containers
|
15
|
+
|
16
|
+
# Configure the header to only have the SVG banner
|
17
|
+
File.open(view.dir/:config/"header.txt", "w") do |f|
|
18
|
+
f.puts "banner_svg"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create a simple SVG config
|
22
|
+
File.open(view.dir/:config/"config.txt", "w") do |f|
|
23
|
+
f.puts "# Simple debug config"
|
24
|
+
f.puts "back.radial #FF0000 #0000FF"
|
25
|
+
f.puts "title.color #FFFFFF"
|
26
|
+
f.puts "subtitle.color #FFFF00"
|
27
|
+
f.puts "title.style bold"
|
28
|
+
f.puts "subtitle.style italic"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generate the front page
|
32
|
+
view.generate_front_page
|
33
|
+
|
34
|
+
instruct <<~EOS
|
35
|
+
SVG Debug Test
|
36
|
+
|
37
|
+
This test has:
|
38
|
+
- Only the SVG banner (no title/subtitle HTML elements)
|
39
|
+
- Red to blue radial gradient
|
40
|
+
- White bold title
|
41
|
+
- Yellow italic subtitle
|
42
|
+
- No header background color
|
43
|
+
|
44
|
+
Check if the SVG displays correctly now.
|
45
|
+
EOS
|
46
|
+
|
47
|
+
examine view
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require_relative "./environment"
|
2
|
+
|
3
|
+
manual_setup
|
4
|
+
|
5
|
+
@repo.create_view("testview", "Test View", "A test view for manual inspection")
|
6
|
+
|
7
|
+
# Enable syntax highlighting for this test by adding it to global-head.txt
|
8
|
+
global_head_file = "test/scriptorium-TEST/views/testview/config/global-head.txt"
|
9
|
+
File.open(global_head_file, "a") { |f| f.puts "syntax # Enable Rouge syntax highlighting" }
|
10
|
+
|
11
|
+
# Post with Rouge syntax highlighting for multiple languages
|
12
|
+
draft_body = <<~'BODY'
|
13
|
+
.blurb Testing Rouge syntax highlighting for Ruby, Elixir, and JavaScript.
|
14
|
+
This post tests the integrated Rouge syntax highlighter with three different programming languages.
|
15
|
+
|
16
|
+
## Ruby Code Example
|
17
|
+
|
18
|
+
.code ruby
|
19
|
+
class User
|
20
|
+
attr_accessor :name, :email
|
21
|
+
|
22
|
+
def initialize(name, email)
|
23
|
+
@name = name
|
24
|
+
@email = email
|
25
|
+
end
|
26
|
+
|
27
|
+
def greet
|
28
|
+
puts "Hello, #{@name}!"
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_email?
|
32
|
+
email.match?(/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z/i)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
user = User.new("Alice", "alice@example.com")
|
37
|
+
user.greet
|
38
|
+
.end
|
39
|
+
|
40
|
+
## Elixir Code Example
|
41
|
+
|
42
|
+
.code elixir
|
43
|
+
defmodule Calculator do
|
44
|
+
def add(a, b), do: a + b
|
45
|
+
def subtract(a, b), do: a - b
|
46
|
+
def multiply(a, b), do: a * b
|
47
|
+
def divide(a, b) when b != 0, do: a / b
|
48
|
+
def divide(_, 0), do: {:error, "Division by zero"}
|
49
|
+
|
50
|
+
def calculate(operation, a, b) do
|
51
|
+
case operation do
|
52
|
+
:add -> add(a, b)
|
53
|
+
:subtract -> subtract(a, b)
|
54
|
+
:multiply -> multiply(a, b)
|
55
|
+
:divide -> divide(a, b)
|
56
|
+
_ -> {:error, "Unknown operation"}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Test the calculator
|
62
|
+
IO.puts("5 + 3 = 8")
|
63
|
+
.end
|
64
|
+
|
65
|
+
## JavaScript Code Example
|
66
|
+
|
67
|
+
.code javascript
|
68
|
+
class TodoList {
|
69
|
+
constructor() {
|
70
|
+
this.todos = [];
|
71
|
+
this.nextId = 1;
|
72
|
+
}
|
73
|
+
|
74
|
+
addTodo(text, completed = false) {
|
75
|
+
const todo = {
|
76
|
+
id: this.nextId++,
|
77
|
+
text: text,
|
78
|
+
completed: completed,
|
79
|
+
createdAt: new Date()
|
80
|
+
};
|
81
|
+
|
82
|
+
this.todos.push(todo);
|
83
|
+
return todo;
|
84
|
+
}
|
85
|
+
|
86
|
+
toggleTodo(id) {
|
87
|
+
const todo = this.todos.find(t => t.id === id);
|
88
|
+
if (todo) {
|
89
|
+
todo.completed = !todo.completed;
|
90
|
+
}
|
91
|
+
return todo;
|
92
|
+
}
|
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
|
+
}
|
110
|
+
|
111
|
+
// Usage example
|
112
|
+
const todoList = new TodoList();
|
113
|
+
todoList.addTodo("Learn Rouge syntax highlighting");
|
114
|
+
todoList.addTodo("Test multiple languages");
|
115
|
+
todoList.addTodo("Write documentation", true);
|
116
|
+
|
117
|
+
console.log("Pending todos:", todoList.getPendingTodos().length);
|
118
|
+
console.log("Completed todos:", todoList.getCompletedTodos().length);
|
119
|
+
.end
|
120
|
+
|
121
|
+
## Test Results
|
122
|
+
|
123
|
+
Each code block above should display with proper syntax highlighting:
|
124
|
+
|
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
|
128
|
+
|
129
|
+
The highlighting should work automatically thanks to our Rouge integration!
|
130
|
+
BODY
|
131
|
+
|
132
|
+
name = @repo.create_draft(title: "Rouge Syntax Highlighting Test", views: ["testview"], body: draft_body)
|
133
|
+
num = @repo.finish_draft(name)
|
134
|
+
@repo.generate_post(num)
|
135
|
+
|
136
|
+
@repo.generate_front_page("testview")
|
137
|
+
|
138
|
+
instruct <<~EOS
|
139
|
+
Front page should have one post with Rouge syntax highlighting.
|
140
|
+
Ruby code should be highlighted with Ruby syntax (keywords red, strings blue, variables orange).
|
141
|
+
Elixir code should be highlighted with Elixir syntax (functions purple, atoms green, strings blue).
|
142
|
+
JavaScript code should be highlighted with JS syntax (keywords red, functions purple, strings blue).
|
143
|
+
Check that Rouge CSS is included in the generated HTML.
|
144
|
+
All code blocks should have proper token classes and syntax highlighting.
|
145
|
+
EOS
|
146
|
+
|
147
|
+
examine("testview")
|
@@ -0,0 +1 @@
|
|
1
|
+
demo
|