scriptorium 0.0.3 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. checksums.yaml +4 -4
  2. data/README.lt3 +324 -0
  3. data/README.md +3155 -1
  4. data/assets/.DS_Store +0 -0
  5. data/assets/README.md +44 -0
  6. data/assets/icons/social/reddit.png +0 -0
  7. data/assets/icons/social/x-logo.png +0 -0
  8. data/assets/icons/ui/.DS_Store +0 -0
  9. data/assets/icons/ui/back.png +0 -0
  10. data/assets/icons/ui/copy.png +0 -0
  11. data/assets/icons/ui/down.png +0 -0
  12. data/assets/icons/ui/end.png +0 -0
  13. data/assets/icons/ui/exit.png +0 -0
  14. data/assets/icons/ui/foo +10 -0
  15. data/assets/icons/ui/home.png +0 -0
  16. data/assets/icons/ui/left.png +0 -0
  17. data/assets/icons/ui/next.png +0 -0
  18. data/assets/icons/ui/right.png +0 -0
  19. data/assets/icons/ui/start.png +0 -0
  20. data/assets/icons/ui/up.png +0 -0
  21. data/assets/imagenotfound.jpg +0 -0
  22. data/assets/samples/placeholder.svg +9 -0
  23. data/assets/themes/standard/favicon.svg +6 -0
  24. data/bin/sblog +84 -5
  25. data/bin/scriptorium +1 -0
  26. data/doc/README.txt +6 -0
  27. data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
  28. data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
  29. data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
  30. data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
  31. data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
  32. data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
  33. data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
  34. data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
  35. data/doc/anti-amnesia/20250807-213025.md +116 -0
  36. data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
  37. data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
  38. data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
  39. data/doc/banner_svg_config.md +114 -0
  40. data/doc/contrib.lt3 +8 -0
  41. data/doc/dependencies.md +281 -0
  42. data/doc/hacker.lt3 +5 -0
  43. data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
  44. data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
  45. data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
  46. data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
  47. data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
  48. data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
  49. data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
  50. data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
  51. data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
  52. data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
  53. data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
  54. data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
  55. data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
  56. data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
  57. data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
  58. data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
  59. data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
  60. data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
  61. data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
  62. data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
  63. data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
  64. data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
  65. data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
  66. data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
  67. data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
  68. data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
  69. data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
  70. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
  71. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
  72. data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
  73. data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
  74. data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
  75. data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
  76. data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
  77. data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
  78. data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
  79. data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
  80. data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
  81. data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
  82. data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
  83. data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
  84. data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
  85. data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
  86. data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
  87. data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
  88. data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
  89. data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
  90. data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
  91. data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
  92. data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
  93. data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
  94. data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
  95. data/doc/imported/0018-ruby-puns/post.html +46 -0
  96. data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
  97. data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
  98. data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
  99. data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
  100. data/doc/imported/0020-fffff/metadata.txt +7 -0
  101. data/doc/imported/0020-fffff/post.html +24 -0
  102. data/doc/imported/0020-fffff/source.lt3 +12 -0
  103. data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
  104. data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
  105. data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
  106. data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
  107. data/doc/imported/0023-doctor-sleep/post.html +63 -0
  108. data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
  109. data/doc/imported/0024-just-a-test/metadata.txt +7 -0
  110. data/doc/imported/0024-just-a-test/post.html +24 -0
  111. data/doc/imported/0024-just-a-test/source.lt3 +12 -0
  112. data/doc/imported/import_summary.txt +98 -0
  113. data/doc/livetext-informal-spec.txt +65 -0
  114. data/doc/myuserdoc/ch-0.lt3 +31 -0
  115. data/doc/myuserdoc/ch-1.lt3 +37 -0
  116. data/doc/myuserdoc/ch-10.lt3 +22 -0
  117. data/doc/myuserdoc/ch-2.lt3 +37 -0
  118. data/doc/myuserdoc/ch-3.lt3 +19 -0
  119. data/doc/myuserdoc/ch-4.lt3 +43 -0
  120. data/doc/myuserdoc/ch-5.lt3 +22 -0
  121. data/doc/myuserdoc/ch-6.lt3 +19 -0
  122. data/doc/myuserdoc/ch-7.lt3 +16 -0
  123. data/doc/myuserdoc/ch-8.lt3 +13 -0
  124. data/doc/myuserdoc/ch-9.lt3 +19 -0
  125. data/doc/myuserdoc/tweak.rb +18 -0
  126. data/doc/myuserdoc/userdoc-toc.txt +88 -0
  127. data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
  128. data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
  129. data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
  130. data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
  131. data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
  132. data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
  133. data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
  134. data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
  135. data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
  136. data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
  137. data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
  138. data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
  139. data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
  140. data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
  141. data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
  142. data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
  143. data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
  144. data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
  145. data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
  146. data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
  147. data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
  148. data/doc/old-posts/0024-just-a-test.lt3 +12 -0
  149. data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
  150. data/doc/old-repo +1 -0
  151. data/doc/reddit_credentials_template.json +8 -0
  152. data/doc/reddit_integration.md +207 -0
  153. data/doc/user.lt3 +35 -0
  154. data/doc/user_guide_section_1.md +137 -0
  155. data/doc/user_guide_section_10.md +515 -0
  156. data/doc/user_guide_section_11.md +708 -0
  157. data/doc/user_guide_section_2.md +233 -0
  158. data/doc/user_guide_section_3.md +5 -0
  159. data/doc/user_guide_section_4.md +221 -0
  160. data/doc/user_guide_section_5.md +243 -0
  161. data/doc/user_guide_section_6.md +147 -0
  162. data/doc/user_guide_section_7.md +311 -0
  163. data/doc/user_guide_section_8.md +224 -0
  164. data/doc/user_guide_section_9.md +375 -0
  165. data/lib/rouge/lexers/livetext.rb +74 -0
  166. data/lib/scriptorium/api.rb +2373 -0
  167. data/lib/scriptorium/banner_svg.rb +729 -0
  168. data/lib/scriptorium/contract.rb +34 -0
  169. data/lib/scriptorium/exceptions.rb +201 -1
  170. data/lib/scriptorium/helpers.rb +675 -0
  171. data/lib/scriptorium/post.rb +259 -0
  172. data/lib/scriptorium/reddit.rb +83 -0
  173. data/lib/scriptorium/repo.rb +938 -0
  174. data/lib/scriptorium/standard_files.rb +149 -0
  175. data/lib/scriptorium/support/bootstrap/css.txt +5 -0
  176. data/lib/scriptorium/support/bootstrap/js.txt +4 -0
  177. data/lib/scriptorium/support/common_js/clipboard.js +35 -0
  178. data/lib/scriptorium/support/common_js/content-loader.js +187 -0
  179. data/lib/scriptorium/support/common_js/navigation.js +52 -0
  180. data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
  181. data/lib/scriptorium/support/config/reddit.txt +10 -0
  182. data/lib/scriptorium/support/config/reddit_template.txt +17 -0
  183. data/lib/scriptorium/support/config/social.txt +8 -0
  184. data/lib/scriptorium/support/highlight/css.txt +2 -0
  185. data/lib/scriptorium/support/highlight/custom.css +119 -0
  186. data/lib/scriptorium/support/highlight/js.txt +1 -0
  187. data/lib/scriptorium/support/post_index/config.txt +15 -0
  188. data/lib/scriptorium/support/post_index/style.css +55 -0
  189. data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
  190. data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
  191. data/lib/scriptorium/support/templates/layout.txt +5 -0
  192. data/lib/scriptorium/support/templates/post.lt3 +104 -0
  193. data/lib/scriptorium/support/theme/footer.lt3 +2 -0
  194. data/lib/scriptorium/support/theme/header.lt3 +4 -0
  195. data/lib/scriptorium/support/theme/left.lt3 +3 -0
  196. data/lib/scriptorium/support/theme/main.lt3 +5 -0
  197. data/lib/scriptorium/support/theme/right.lt3 +3 -0
  198. data/lib/scriptorium/theme.rb +192 -0
  199. data/lib/scriptorium/version.rb +1 -1
  200. data/lib/scriptorium/view.rb +1021 -0
  201. data/lib/scriptorium/widgets/featured_posts.rb +149 -0
  202. data/lib/scriptorium/widgets/links.rb +112 -0
  203. data/lib/scriptorium/widgets/pages.rb +133 -0
  204. data/lib/scriptorium/widgets/widget.rb +133 -0
  205. data/lib/scriptorium.rb +38 -34
  206. data/lib/skeleton.rb +10 -1
  207. data/scriptorium.gemspec +17 -5
  208. data/test/README.md +69 -0
  209. data/test/WEB_INTEGRATION_README.md +196 -0
  210. data/test/all +83 -0
  211. data/test/api_demo.rb +99 -0
  212. data/test/assets/imagenotfound.jpg +0 -0
  213. data/test/assets/images/.DS_Store +0 -0
  214. data/test/assets/images/README.md +27 -0
  215. data/test/assets/images/odd_aspect.png +0 -0
  216. data/test/assets/images/perfect.png +0 -0
  217. data/test/assets/images/small.png +0 -0
  218. data/test/assets/images/tall.png +0 -0
  219. data/test/assets/images/very_tall.png +0 -0
  220. data/test/assets/images/very_wide.png +0 -0
  221. data/test/assets/images/wide.png +0 -0
  222. data/test/assets/testbanner.jpg +0 -0
  223. data/test/banner_svg/simple_helpers.rb +13 -0
  224. data/test/banner_svg/unit.rb +1000 -0
  225. data/test/config/deployment.txt +5 -0
  226. data/test/ed_test.rb +204 -0
  227. data/test/integration/cursor_banner_combinations.rb +193 -0
  228. data/test/integration/cursor_banner_features.rb +374 -0
  229. data/test/integration/integration_test.rb +326 -0
  230. data/test/integration/preview_flow_test.rb +94 -0
  231. data/test/livetext_plugin_test.rb +500 -0
  232. data/test/manual/asset_mgmt.rb +67 -0
  233. data/test/manual/banner-tests/index.html +45 -0
  234. data/test/manual/banner-tests/svg.txt +3 -0
  235. data/test/manual/banner-tests/test01.html +122 -0
  236. data/test/manual/banner-tests/test02.html +122 -0
  237. data/test/manual/banner-tests/test03.html +122 -0
  238. data/test/manual/banner-tests/test04.html +129 -0
  239. data/test/manual/banner-tests/test05.html +129 -0
  240. data/test/manual/banner-tests/test06.html +129 -0
  241. data/test/manual/banner-tests/test07.html +129 -0
  242. data/test/manual/banner-tests/test08.html +123 -0
  243. data/test/manual/banner-tests/test09.html +123 -0
  244. data/test/manual/banner-tests/test10.html +123 -0
  245. data/test/manual/banner-tests/test11.html +123 -0
  246. data/test/manual/banner-tests/test12.html +123 -0
  247. data/test/manual/banner-tests/test13.html +123 -0
  248. data/test/manual/banner-tests/test14.html +123 -0
  249. data/test/manual/banner-tests/test15.html +122 -0
  250. data/test/manual/banner-tests/test16.html +122 -0
  251. data/test/manual/banner-tests/test17.html +122 -0
  252. data/test/manual/banner-tests/test18.html +132 -0
  253. data/test/manual/banner-tests/test19.html +132 -0
  254. data/test/manual/banner-tests/test20.html +132 -0
  255. data/test/manual/banner-tests/test21.html +132 -0
  256. data/test/manual/banner-tests/test22.html +132 -0
  257. data/test/manual/banner-tests/test23.html +132 -0
  258. data/test/manual/banner-tests/test24.html +132 -0
  259. data/test/manual/banner-tests/test25.html +131 -0
  260. data/test/manual/banner_environment.rb +205 -0
  261. data/test/manual/codemirror_demo.html +773 -0
  262. data/test/manual/create_posts_for_web.rb +114 -0
  263. data/test/manual/environment.rb +67 -0
  264. data/test/manual/make_banner.rb +153 -0
  265. data/test/manual/preview_manual_test.rb +129 -0
  266. data/test/manual/sample_banner_config.txt +12 -0
  267. data/test/manual/test_advanced_widgets.rb +73 -0
  268. data/test/manual/test_banner_combinations.rb +120 -0
  269. data/test/manual/test_banner_features.rb +306 -0
  270. data/test/manual/test_banner_integration.rb +115 -0
  271. data/test/manual/test_banner_radial.rb +87 -0
  272. data/test/manual/test_basic_posts.rb +47 -0
  273. data/test/manual/test_layout_widgets.rb +40 -0
  274. data/test/manual/test_pagination.rb +24 -0
  275. data/test/manual/test_random_posts.rb +38 -0
  276. data/test/manual/test_syntax_highlighting.rb +167 -0
  277. data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
  278. data/test/rubytext/rubytext_demo_test.rb +42 -0
  279. data/test/rubytext/rubytext_testing_guide.md +277 -0
  280. data/test/run_automated_tests.rb +45 -0
  281. data/test/staging/.DS_Store +0 -0
  282. data/test/support/preview_utils.rb +88 -0
  283. data/test/syntax_highlighting_test.lt3 +124 -0
  284. data/test/test_gem_assets.rb +48 -0
  285. data/test/test_helpers.rb +240 -0
  286. data/test/tui_editor_integration_test.rb +296 -0
  287. data/test/tui_integration_test.rb +883 -0
  288. data/test/unit/api.rb +1776 -0
  289. data/test/unit/asset_management.rb +219 -0
  290. data/test/unit/backup_test.rb +451 -0
  291. data/test/unit/clipboard_test.rb +60 -0
  292. data/test/unit/contract_test.rb +69 -0
  293. data/test/unit/core.rb +1211 -0
  294. data/test/unit/deploy_config_test.rb +248 -0
  295. data/test/unit/deploy_test.rb +478 -0
  296. data/test/unit/edit_post_test.rb +168 -0
  297. data/test/unit/gem_asset_management.rb +183 -0
  298. data/test/unit/livetext_basic.rb +57 -0
  299. data/test/unit/livetext_compatibility.rb +82 -0
  300. data/test/unit/parse_cmd_test.rb +260 -0
  301. data/test/unit/permalink_copy_test.rb +211 -0
  302. data/test/unit/post.rb +309 -0
  303. data/test/unit/post_index_config_test.rb +258 -0
  304. data/test/unit/post_state_helpers_test.rb +137 -0
  305. data/test/unit/read_commented_file_test.rb +278 -0
  306. data/test/unit/reddit_test.rb +235 -0
  307. data/test/unit/repo.rb +569 -0
  308. data/test/unit/social_test.rb +366 -0
  309. data/test/unit/syntax_highlighting.rb +70 -0
  310. data/test/unit/theme_management_test.rb +91 -0
  311. data/test/unit/view.rb +498 -0
  312. data/test/unit/widgets.rb +669 -0
  313. data/test/web_integration_test.rb +231 -0
  314. data/test/web_test_helper.rb +218 -0
  315. data/test/web_workflow_test.rb +527 -0
  316. data/test/wizard_test.rb +123 -0
  317. data/ui/README.md +67 -0
  318. data/ui/common/lib/ui_common.rb +8 -0
  319. data/ui/rubytext/README.md +191 -0
  320. data/ui/rubytext/bin/scriptorium-rubytext +402 -0
  321. data/ui/rubytext/lib/rubytext_ui.rb +300 -0
  322. data/ui/tui/bin/scriptorium +1890 -0
  323. data/ui/tui/test/tui_test.rb +23 -0
  324. data/ui/web/app/app.rb +2600 -0
  325. data/ui/web/app/assets/livetext_mode.js +244 -0
  326. data/ui/web/app/error_helpers.rb +150 -0
  327. data/ui/web/app/views/advanced_config.erb +196 -0
  328. data/ui/web/app/views/asset_management.erb +645 -0
  329. data/ui/web/app/views/backup_management.erb +238 -0
  330. data/ui/web/app/views/banner_config.erb +200 -0
  331. data/ui/web/app/views/config_widget.erb +232 -0
  332. data/ui/web/app/views/configure_view.erb +401 -0
  333. data/ui/web/app/views/dashboard.erb +154 -0
  334. data/ui/web/app/views/deploy_config.erb +149 -0
  335. data/ui/web/app/views/edit_pages.erb +363 -0
  336. data/ui/web/app/views/edit_post.erb +175 -0
  337. data/ui/web/app/views/edit_theme.erb +73 -0
  338. data/ui/web/app/views/edit_theme_file.erb +74 -0
  339. data/ui/web/app/views/error_page.erb +29 -0
  340. data/ui/web/app/views/header_config.erb +155 -0
  341. data/ui/web/app/views/layout_config.erb +147 -0
  342. data/ui/web/app/views/navbar_config.erb +411 -0
  343. data/ui/web/app/views/theme_management.erb +130 -0
  344. data/ui/web/app/views/view_dashboard.erb +779 -0
  345. data/ui/web/app/views/widgets.erb +249 -0
  346. data/ui/web/bin/scriptorium-web +164 -0
  347. data/ui/web/test/web_basic_test.rb +38 -0
  348. data/ui/web/test_navbar.txt +7 -0
  349. data/ui/web/tmp/timing.log +17 -0
  350. data/ui/web/tmp/web_server.log +0 -0
  351. metadata +434 -8
  352. data/lib/scriptorium/engine.rb +0 -22
  353. data/test/engine/unit.rb +0 -44
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Bold Text</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
7
+ .banner { width: 100%; margin: 0; padding: 0; border: 3px solid #007cba; border-radius: 8px; }
8
+ .content { padding: 20px; padding-bottom: 80px; }
9
+ .description { margin: 10px 0; font-weight: bold; }
10
+ .config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
11
+ .navigation {
12
+ position: fixed;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+ background: #e0e0e0;
17
+ padding: 15px;
18
+ text-align: center;
19
+ border-top: 2px solid #007cba;
20
+ z-index: 1000;
21
+ }
22
+ .navigation a { margin: 0 10px; padding: 8px 15px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
23
+ .navigation a:hover { background: #005a87; }
24
+ .original-image { margin: 20px 0; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
25
+ .original-image h3 { margin: 0 0 10px 0; color: #333; }
26
+ .original-image img { max-width: 100%; height: auto; border: 1px solid #ddd; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="banner" id="header">
31
+ <script>
32
+ function insert_svg_header(container) {
33
+ const svg_text = ` <svg xmlns='http://www.w3.org/2000/svg'
34
+ width='100%' height='100'
35
+ viewBox='0 0 800 100'
36
+ preserveAspectRatio='xMidYMid meet'>
37
+ <rect x='0' y='0' width='100%' height='100%' fill='#fff' />
38
+ <text x='5%'
39
+ y='52%'
40
+ text-anchor='start'
41
+ style='font-family: Verdana; font-size: 48.0px; font-weight: bold; font-style: normal'
42
+ fill='#374151'>Bold Text</text>
43
+
44
+ <text x='5%'
45
+ y='82%'
46
+ text-anchor='start'
47
+ style='font-family: Verdana; font-size: 24.0px; font-weight: bold; font-style: normal'
48
+ fill='#374151'>Style test</text>
49
+
50
+ </svg>`;
51
+ const svgElement = document.createElement('div');
52
+ svgElement.innerHTML = svg_text;
53
+ const svg = svgElement.firstElementChild;
54
+
55
+ const svgWidth = window.innerWidth;
56
+ const aspectRatio = 8.0;
57
+ const svgHeight = svgWidth / aspectRatio;
58
+
59
+ svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
60
+ svg.setAttribute('width', svgWidth);
61
+ svg.setAttribute('height', svgHeight);
62
+
63
+ const titleFontSize = 0.8 * 60;
64
+ const subtitleFontSize = 0.4 * 60;
65
+
66
+ const te1 = svg.querySelector('text:nth-of-type(1)')
67
+ const te2 = svg.querySelector('text:nth-of-type(2)')
68
+
69
+ // Don't override the styles - they're already set correctly in the SVG
70
+ // Just update the positioning and text-anchor
71
+
72
+ const titleXpct = "5%";
73
+ const titleYpct = "52%";
74
+ const subtitleXpct = "5%";
75
+ const subtitleYpct = "82%";
76
+
77
+ const tX = svgWidth * (parseFloat(titleXpct) / 100);
78
+ const tY = svgHeight * (parseFloat(titleYpct) / 100);
79
+ const sX = svgWidth * (parseFloat(subtitleXpct) / 100);
80
+ const sY = svgHeight * (parseFloat(subtitleYpct) / 100);
81
+
82
+ te1.setAttribute('x', tX);
83
+ te1.setAttribute('y', tY);
84
+ te2.setAttribute('x', sX);
85
+ te2.setAttribute('y', sY);
86
+
87
+ // Set text-anchor for proper positioning (use individual anchors if set)
88
+ te1.setAttribute('text-anchor', 'start');
89
+ te2.setAttribute('text-anchor', 'start');
90
+
91
+ // Apply calculated font sizes
92
+ te1.setAttribute('font-size', titleFontSize + 'px');
93
+ te2.setAttribute('font-size', subtitleFontSize + 'px');
94
+
95
+ const containerElement = document.getElementById(container);
96
+ if (containerElement) {
97
+ console.log('Container found, inserting SVG...');
98
+ containerElement.innerHTML = svg.outerHTML;
99
+ console.log('SVG inserted successfully');
100
+ } else {
101
+ console.error('Container not found:', container);
102
+ }
103
+ }
104
+
105
+ console.log('SVG script loaded');
106
+
107
+ // Use DOMContentLoaded to avoid conflicts with main window.onload
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ console.log('DOM ready, trying SVG insertion...');
110
+ insert_svg_header('header');
111
+ });
112
+ </script>
113
+
114
+ </div>
115
+ <div class="content">
116
+ <div class="description">Bold Text</div>
117
+ <div class="config">title.style bold
118
+ subtitle.style bold</div>
119
+
120
+ <div class="navigation"><a href="index.html">Back to Index</a> <a href="test09.html">Previous</a> <a href="test11.html">Next</a></div>
121
+ </div>
122
+ </body>
123
+ </html>
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Italic Text</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
7
+ .banner { width: 100%; margin: 0; padding: 0; border: 3px solid #007cba; border-radius: 8px; }
8
+ .content { padding: 20px; padding-bottom: 80px; }
9
+ .description { margin: 10px 0; font-weight: bold; }
10
+ .config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
11
+ .navigation {
12
+ position: fixed;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+ background: #e0e0e0;
17
+ padding: 15px;
18
+ text-align: center;
19
+ border-top: 2px solid #007cba;
20
+ z-index: 1000;
21
+ }
22
+ .navigation a { margin: 0 10px; padding: 8px 15px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
23
+ .navigation a:hover { background: #005a87; }
24
+ .original-image { margin: 20px 0; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
25
+ .original-image h3 { margin: 0 0 10px 0; color: #333; }
26
+ .original-image img { max-width: 100%; height: auto; border: 1px solid #ddd; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="banner" id="header">
31
+ <script>
32
+ function insert_svg_header(container) {
33
+ const svg_text = ` <svg xmlns='http://www.w3.org/2000/svg'
34
+ width='100%' height='100'
35
+ viewBox='0 0 800 100'
36
+ preserveAspectRatio='xMidYMid meet'>
37
+ <rect x='0' y='0' width='100%' height='100%' fill='#fff' />
38
+ <text x='5%'
39
+ y='52%'
40
+ text-anchor='start'
41
+ style='font-family: Verdana; font-size: 48.0px; font-weight: normal; font-style: italic'
42
+ fill='#374151'>Italic Text</text>
43
+
44
+ <text x='5%'
45
+ y='82%'
46
+ text-anchor='start'
47
+ style='font-family: Verdana; font-size: 24.0px; font-weight: normal; font-style: italic'
48
+ fill='#374151'>Style test</text>
49
+
50
+ </svg>`;
51
+ const svgElement = document.createElement('div');
52
+ svgElement.innerHTML = svg_text;
53
+ const svg = svgElement.firstElementChild;
54
+
55
+ const svgWidth = window.innerWidth;
56
+ const aspectRatio = 8.0;
57
+ const svgHeight = svgWidth / aspectRatio;
58
+
59
+ svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
60
+ svg.setAttribute('width', svgWidth);
61
+ svg.setAttribute('height', svgHeight);
62
+
63
+ const titleFontSize = 0.8 * 60;
64
+ const subtitleFontSize = 0.4 * 60;
65
+
66
+ const te1 = svg.querySelector('text:nth-of-type(1)')
67
+ const te2 = svg.querySelector('text:nth-of-type(2)')
68
+
69
+ // Don't override the styles - they're already set correctly in the SVG
70
+ // Just update the positioning and text-anchor
71
+
72
+ const titleXpct = "5%";
73
+ const titleYpct = "52%";
74
+ const subtitleXpct = "5%";
75
+ const subtitleYpct = "82%";
76
+
77
+ const tX = svgWidth * (parseFloat(titleXpct) / 100);
78
+ const tY = svgHeight * (parseFloat(titleYpct) / 100);
79
+ const sX = svgWidth * (parseFloat(subtitleXpct) / 100);
80
+ const sY = svgHeight * (parseFloat(subtitleYpct) / 100);
81
+
82
+ te1.setAttribute('x', tX);
83
+ te1.setAttribute('y', tY);
84
+ te2.setAttribute('x', sX);
85
+ te2.setAttribute('y', sY);
86
+
87
+ // Set text-anchor for proper positioning (use individual anchors if set)
88
+ te1.setAttribute('text-anchor', 'start');
89
+ te2.setAttribute('text-anchor', 'start');
90
+
91
+ // Apply calculated font sizes
92
+ te1.setAttribute('font-size', titleFontSize + 'px');
93
+ te2.setAttribute('font-size', subtitleFontSize + 'px');
94
+
95
+ const containerElement = document.getElementById(container);
96
+ if (containerElement) {
97
+ console.log('Container found, inserting SVG...');
98
+ containerElement.innerHTML = svg.outerHTML;
99
+ console.log('SVG inserted successfully');
100
+ } else {
101
+ console.error('Container not found:', container);
102
+ }
103
+ }
104
+
105
+ console.log('SVG script loaded');
106
+
107
+ // Use DOMContentLoaded to avoid conflicts with main window.onload
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ console.log('DOM ready, trying SVG insertion...');
110
+ insert_svg_header('header');
111
+ });
112
+ </script>
113
+
114
+ </div>
115
+ <div class="content">
116
+ <div class="description">Italic Text</div>
117
+ <div class="config">title.style italic
118
+ subtitle.style italic</div>
119
+
120
+ <div class="navigation"><a href="index.html">Back to Index</a> <a href="test10.html">Previous</a> <a href="test12.html">Next</a></div>
121
+ </div>
122
+ </body>
123
+ </html>
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Bold & Italic</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
7
+ .banner { width: 100%; margin: 0; padding: 0; border: 3px solid #007cba; border-radius: 8px; }
8
+ .content { padding: 20px; padding-bottom: 80px; }
9
+ .description { margin: 10px 0; font-weight: bold; }
10
+ .config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
11
+ .navigation {
12
+ position: fixed;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+ background: #e0e0e0;
17
+ padding: 15px;
18
+ text-align: center;
19
+ border-top: 2px solid #007cba;
20
+ z-index: 1000;
21
+ }
22
+ .navigation a { margin: 0 10px; padding: 8px 15px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
23
+ .navigation a:hover { background: #005a87; }
24
+ .original-image { margin: 20px 0; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
25
+ .original-image h3 { margin: 0 0 10px 0; color: #333; }
26
+ .original-image img { max-width: 100%; height: auto; border: 1px solid #ddd; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="banner" id="header">
31
+ <script>
32
+ function insert_svg_header(container) {
33
+ const svg_text = ` <svg xmlns='http://www.w3.org/2000/svg'
34
+ width='100%' height='100'
35
+ viewBox='0 0 800 100'
36
+ preserveAspectRatio='xMidYMid meet'>
37
+ <rect x='0' y='0' width='100%' height='100%' fill='#fff' />
38
+ <text x='5%'
39
+ y='52%'
40
+ text-anchor='start'
41
+ style='font-family: Verdana; font-size: 48.0px; font-weight: bold; font-style: italic'
42
+ fill='#374151'>Bold & Italic</text>
43
+
44
+ <text x='5%'
45
+ y='82%'
46
+ text-anchor='start'
47
+ style='font-family: Verdana; font-size: 24.0px; font-weight: bold; font-style: italic'
48
+ fill='#374151'>Style test</text>
49
+
50
+ </svg>`;
51
+ const svgElement = document.createElement('div');
52
+ svgElement.innerHTML = svg_text;
53
+ const svg = svgElement.firstElementChild;
54
+
55
+ const svgWidth = window.innerWidth;
56
+ const aspectRatio = 8.0;
57
+ const svgHeight = svgWidth / aspectRatio;
58
+
59
+ svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
60
+ svg.setAttribute('width', svgWidth);
61
+ svg.setAttribute('height', svgHeight);
62
+
63
+ const titleFontSize = 0.8 * 60;
64
+ const subtitleFontSize = 0.4 * 60;
65
+
66
+ const te1 = svg.querySelector('text:nth-of-type(1)')
67
+ const te2 = svg.querySelector('text:nth-of-type(2)')
68
+
69
+ // Don't override the styles - they're already set correctly in the SVG
70
+ // Just update the positioning and text-anchor
71
+
72
+ const titleXpct = "5%";
73
+ const titleYpct = "52%";
74
+ const subtitleXpct = "5%";
75
+ const subtitleYpct = "82%";
76
+
77
+ const tX = svgWidth * (parseFloat(titleXpct) / 100);
78
+ const tY = svgHeight * (parseFloat(titleYpct) / 100);
79
+ const sX = svgWidth * (parseFloat(subtitleXpct) / 100);
80
+ const sY = svgHeight * (parseFloat(subtitleYpct) / 100);
81
+
82
+ te1.setAttribute('x', tX);
83
+ te1.setAttribute('y', tY);
84
+ te2.setAttribute('x', sX);
85
+ te2.setAttribute('y', sY);
86
+
87
+ // Set text-anchor for proper positioning (use individual anchors if set)
88
+ te1.setAttribute('text-anchor', 'start');
89
+ te2.setAttribute('text-anchor', 'start');
90
+
91
+ // Apply calculated font sizes
92
+ te1.setAttribute('font-size', titleFontSize + 'px');
93
+ te2.setAttribute('font-size', subtitleFontSize + 'px');
94
+
95
+ const containerElement = document.getElementById(container);
96
+ if (containerElement) {
97
+ console.log('Container found, inserting SVG...');
98
+ containerElement.innerHTML = svg.outerHTML;
99
+ console.log('SVG inserted successfully');
100
+ } else {
101
+ console.error('Container not found:', container);
102
+ }
103
+ }
104
+
105
+ console.log('SVG script loaded');
106
+
107
+ // Use DOMContentLoaded to avoid conflicts with main window.onload
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ console.log('DOM ready, trying SVG insertion...');
110
+ insert_svg_header('header');
111
+ });
112
+ </script>
113
+
114
+ </div>
115
+ <div class="content">
116
+ <div class="description">Bold & Italic Text</div>
117
+ <div class="config">title.style bold italic
118
+ subtitle.style bold italic</div>
119
+
120
+ <div class="navigation"><a href="index.html">Back to Index</a> <a href="test11.html">Previous</a> <a href="test13.html">Next</a></div>
121
+ </div>
122
+ </body>
123
+ </html>
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Blue Text</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
7
+ .banner { width: 100%; margin: 0; padding: 0; border: 3px solid #007cba; border-radius: 8px; }
8
+ .content { padding: 20px; padding-bottom: 80px; }
9
+ .description { margin: 10px 0; font-weight: bold; }
10
+ .config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
11
+ .navigation {
12
+ position: fixed;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+ background: #e0e0e0;
17
+ padding: 15px;
18
+ text-align: center;
19
+ border-top: 2px solid #007cba;
20
+ z-index: 1000;
21
+ }
22
+ .navigation a { margin: 0 10px; padding: 8px 15px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
23
+ .navigation a:hover { background: #005a87; }
24
+ .original-image { margin: 20px 0; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
25
+ .original-image h3 { margin: 0 0 10px 0; color: #333; }
26
+ .original-image img { max-width: 100%; height: auto; border: 1px solid #ddd; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="banner" id="header">
31
+ <script>
32
+ function insert_svg_header(container) {
33
+ const svg_text = ` <svg xmlns='http://www.w3.org/2000/svg'
34
+ width='100%' height='100'
35
+ viewBox='0 0 800 100'
36
+ preserveAspectRatio='xMidYMid meet'>
37
+ <rect x='0' y='0' width='100%' height='100%' fill='#fff' />
38
+ <text x='5%'
39
+ y='52%'
40
+ text-anchor='start'
41
+ style='font-family: Verdana; font-size: 48.0px; font-weight: normal; font-style: normal'
42
+ fill='#0000ff'>Blue Text</text>
43
+
44
+ <text x='5%'
45
+ y='82%'
46
+ text-anchor='start'
47
+ style='font-family: Verdana; font-size: 24.0px; font-weight: normal; font-style: normal'
48
+ fill='#0000ff'>Color test</text>
49
+
50
+ </svg>`;
51
+ const svgElement = document.createElement('div');
52
+ svgElement.innerHTML = svg_text;
53
+ const svg = svgElement.firstElementChild;
54
+
55
+ const svgWidth = window.innerWidth;
56
+ const aspectRatio = 8.0;
57
+ const svgHeight = svgWidth / aspectRatio;
58
+
59
+ svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
60
+ svg.setAttribute('width', svgWidth);
61
+ svg.setAttribute('height', svgHeight);
62
+
63
+ const titleFontSize = 0.8 * 60;
64
+ const subtitleFontSize = 0.4 * 60;
65
+
66
+ const te1 = svg.querySelector('text:nth-of-type(1)')
67
+ const te2 = svg.querySelector('text:nth-of-type(2)')
68
+
69
+ // Don't override the styles - they're already set correctly in the SVG
70
+ // Just update the positioning and text-anchor
71
+
72
+ const titleXpct = "5%";
73
+ const titleYpct = "52%";
74
+ const subtitleXpct = "5%";
75
+ const subtitleYpct = "82%";
76
+
77
+ const tX = svgWidth * (parseFloat(titleXpct) / 100);
78
+ const tY = svgHeight * (parseFloat(titleYpct) / 100);
79
+ const sX = svgWidth * (parseFloat(subtitleXpct) / 100);
80
+ const sY = svgHeight * (parseFloat(subtitleYpct) / 100);
81
+
82
+ te1.setAttribute('x', tX);
83
+ te1.setAttribute('y', tY);
84
+ te2.setAttribute('x', sX);
85
+ te2.setAttribute('y', sY);
86
+
87
+ // Set text-anchor for proper positioning (use individual anchors if set)
88
+ te1.setAttribute('text-anchor', 'start');
89
+ te2.setAttribute('text-anchor', 'start');
90
+
91
+ // Apply calculated font sizes
92
+ te1.setAttribute('font-size', titleFontSize + 'px');
93
+ te2.setAttribute('font-size', subtitleFontSize + 'px');
94
+
95
+ const containerElement = document.getElementById(container);
96
+ if (containerElement) {
97
+ console.log('Container found, inserting SVG...');
98
+ containerElement.innerHTML = svg.outerHTML;
99
+ console.log('SVG inserted successfully');
100
+ } else {
101
+ console.error('Container not found:', container);
102
+ }
103
+ }
104
+
105
+ console.log('SVG script loaded');
106
+
107
+ // Use DOMContentLoaded to avoid conflicts with main window.onload
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ console.log('DOM ready, trying SVG insertion...');
110
+ insert_svg_header('header');
111
+ });
112
+ </script>
113
+
114
+ </div>
115
+ <div class="content">
116
+ <div class="description">Blue Text</div>
117
+ <div class="config">title.color #0000ff
118
+ subtitle.color #0000ff</div>
119
+
120
+ <div class="navigation"><a href="index.html">Back to Index</a> <a href="test12.html">Previous</a> <a href="test14.html">Next</a></div>
121
+ </div>
122
+ </body>
123
+ </html>
@@ -0,0 +1,123 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Green Text</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background: #f5f5f5; }
7
+ .banner { width: 100%; margin: 0; padding: 0; border: 3px solid #007cba; border-radius: 8px; }
8
+ .content { padding: 20px; padding-bottom: 80px; }
9
+ .description { margin: 10px 0; font-weight: bold; }
10
+ .config { background: #f0f0f0; padding: 10px; margin: 10px 0; font-family: monospace; font-size: 12px; }
11
+ .navigation {
12
+ position: fixed;
13
+ bottom: 0;
14
+ left: 0;
15
+ right: 0;
16
+ background: #e0e0e0;
17
+ padding: 15px;
18
+ text-align: center;
19
+ border-top: 2px solid #007cba;
20
+ z-index: 1000;
21
+ }
22
+ .navigation a { margin: 0 10px; padding: 8px 15px; background: #007cba; color: white; text-decoration: none; border-radius: 3px; }
23
+ .navigation a:hover { background: #005a87; }
24
+ .original-image { margin: 20px 0; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
25
+ .original-image h3 { margin: 0 0 10px 0; color: #333; }
26
+ .original-image img { max-width: 100%; height: auto; border: 1px solid #ddd; }
27
+ </style>
28
+ </head>
29
+ <body>
30
+ <div class="banner" id="header">
31
+ <script>
32
+ function insert_svg_header(container) {
33
+ const svg_text = ` <svg xmlns='http://www.w3.org/2000/svg'
34
+ width='100%' height='100'
35
+ viewBox='0 0 800 100'
36
+ preserveAspectRatio='xMidYMid meet'>
37
+ <rect x='0' y='0' width='100%' height='100%' fill='#fff' />
38
+ <text x='5%'
39
+ y='52%'
40
+ text-anchor='start'
41
+ style='font-family: Verdana; font-size: 48.0px; font-weight: normal; font-style: normal'
42
+ fill='#00ff00'>Green Text</text>
43
+
44
+ <text x='5%'
45
+ y='82%'
46
+ text-anchor='start'
47
+ style='font-family: Verdana; font-size: 24.0px; font-weight: normal; font-style: normal'
48
+ fill='#00ff00'>Color test</text>
49
+
50
+ </svg>`;
51
+ const svgElement = document.createElement('div');
52
+ svgElement.innerHTML = svg_text;
53
+ const svg = svgElement.firstElementChild;
54
+
55
+ const svgWidth = window.innerWidth;
56
+ const aspectRatio = 8.0;
57
+ const svgHeight = svgWidth / aspectRatio;
58
+
59
+ svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);
60
+ svg.setAttribute('width', svgWidth);
61
+ svg.setAttribute('height', svgHeight);
62
+
63
+ const titleFontSize = 0.8 * 60;
64
+ const subtitleFontSize = 0.4 * 60;
65
+
66
+ const te1 = svg.querySelector('text:nth-of-type(1)')
67
+ const te2 = svg.querySelector('text:nth-of-type(2)')
68
+
69
+ // Don't override the styles - they're already set correctly in the SVG
70
+ // Just update the positioning and text-anchor
71
+
72
+ const titleXpct = "5%";
73
+ const titleYpct = "52%";
74
+ const subtitleXpct = "5%";
75
+ const subtitleYpct = "82%";
76
+
77
+ const tX = svgWidth * (parseFloat(titleXpct) / 100);
78
+ const tY = svgHeight * (parseFloat(titleYpct) / 100);
79
+ const sX = svgWidth * (parseFloat(subtitleXpct) / 100);
80
+ const sY = svgHeight * (parseFloat(subtitleYpct) / 100);
81
+
82
+ te1.setAttribute('x', tX);
83
+ te1.setAttribute('y', tY);
84
+ te2.setAttribute('x', sX);
85
+ te2.setAttribute('y', sY);
86
+
87
+ // Set text-anchor for proper positioning (use individual anchors if set)
88
+ te1.setAttribute('text-anchor', 'start');
89
+ te2.setAttribute('text-anchor', 'start');
90
+
91
+ // Apply calculated font sizes
92
+ te1.setAttribute('font-size', titleFontSize + 'px');
93
+ te2.setAttribute('font-size', subtitleFontSize + 'px');
94
+
95
+ const containerElement = document.getElementById(container);
96
+ if (containerElement) {
97
+ console.log('Container found, inserting SVG...');
98
+ containerElement.innerHTML = svg.outerHTML;
99
+ console.log('SVG inserted successfully');
100
+ } else {
101
+ console.error('Container not found:', container);
102
+ }
103
+ }
104
+
105
+ console.log('SVG script loaded');
106
+
107
+ // Use DOMContentLoaded to avoid conflicts with main window.onload
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ console.log('DOM ready, trying SVG insertion...');
110
+ insert_svg_header('header');
111
+ });
112
+ </script>
113
+
114
+ </div>
115
+ <div class="content">
116
+ <div class="description">Green Text</div>
117
+ <div class="config">title.color #00ff00
118
+ subtitle.color #00ff00</div>
119
+
120
+ <div class="navigation"><a href="index.html">Back to Index</a> <a href="test13.html">Previous</a> <a href="test15.html">Next</a></div>
121
+ </div>
122
+ </body>
123
+ </html>