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,27 @@
1
+ # Anti-Amnesia Timestamping Fix
2
+
3
+ **Date**: 2025-08-04 19:07:00
4
+ **Issue**: Anti-amnesia file created with incorrect timestamp in filename
5
+ **Status**: Fixed
6
+
7
+ ## Problem
8
+ The file `20250728-143000-cognitive-loop-bug.md` was created today (August 4th, 2025) but had an incorrect timestamp in its filename showing July 28th, 2025.
9
+
10
+ ## Root Cause
11
+ The anti-amnesia system appears to have used an old timestamp when creating the file, possibly from:
12
+ - Cached timestamp from previous session
13
+ - System clock issues
14
+ - Manual timestamp entry error
15
+
16
+ ## Solution
17
+ Renamed the file to use the correct current timestamp:
18
+ - **From**: `20250728-143000-cognitive-loop-bug.md`
19
+ - **To**: `20250804-190500-cognitive-loop-bug.md`
20
+
21
+ ## Prevention
22
+ - Anti-amnesia files should always be created with the CURRENT timestamp
23
+ - Use `date +%Y%m%d-%H%M%S` format for consistent timestamping
24
+ - Verify timestamp accuracy before creating files
25
+
26
+ ## Key Takeaway
27
+ Always use current timestamps when creating anti-amnesia files to maintain accurate chronological order and prevent confusion.
@@ -0,0 +1,116 @@
1
+
2
+ # Livetext Knowledge Summary
3
+
4
+ ## Overview
5
+ Livetext is a text processing system that transforms plain text files into HTML output. It's designed to be simple and non-Turing-complete, supporting minimal nesting and currently no branching. It's used extensively in projects like Scriptorium (a blogging tool).
6
+
7
+ ## Core Architecture
8
+ - Main class: `Livetext` (in lib/livetext/core.rb)
9
+ - Previously had a circular dependency between `Livetext` and `Processor` classes
10
+ - Recently refactored to merge `Processor` into `Livetext` to eliminate circular dependency
11
+ - Uses a stack-based source management system (`@sources`) for handling nested includes
12
+
13
+ ## Key Components
14
+ 1. **Livetext::Core** - Main processing class
15
+ 2. **Livetext::Standard** - Built-in dot commands (lib/livetext/standard.rb)
16
+ 3. **Livetext::Expansion** - Variable and function expansion (lib/livetext/expansion.rb)
17
+ 4. **Livetext::UserAPI** - API for dot commands (lib/livetext/userapi.rb)
18
+ 5. **Livetext::VariableManager** - Manages variables
19
+ 6. **Livetext::HTML** - HTML generation utilities
20
+
21
+ ## Processing Methods
22
+ - `process(text: nil, file: nil, vars: {})` - New unified method, returns [body, vars]
23
+ - `transform(text)` - Legacy method, returns body only
24
+ - `xform(*args, file: nil, text: nil, vars: {})` - Legacy wrapper
25
+ - `xform_file(file, vars: nil)` - Legacy wrapper
26
+
27
+ ## Dot Commands
28
+ Dot commands start with `.` and control Livetext's behavior. They can have different parameter signatures:
29
+
30
+ 1. **No parameters**: `.def mymeth`
31
+ 2. **Args + data**: `.def mymeth args`
32
+ 3. **Args + data + body**: `.def mymeth body`
33
+ 4. **Args + data + raw body**: `.def mymeth body raw` (NEW)
34
+
35
+ Examples:
36
+ - `.set VAR="value"` - Set variables
37
+ - `.h1 Title` - Generate HTML headings
38
+ - `.def mymethod` - Define custom methods
39
+ - `.include file.inc` - Include other files
40
+ - `.func myfunction` - Define functions
41
+
42
+ ## Functions
43
+ Functions are called with `$$funcname[param]` syntax:
44
+ - `$$func[]` - Passes empty string `""` as parameter
45
+ - `$$func[""]` - Passes literal empty string `'""'` as parameter
46
+ - `$$func[value]` - Passes `value` as parameter
47
+
48
+ Functions are never passed `nil` - empty brackets result in empty string.
49
+
50
+ ## Variables
51
+ - Set with `.set VAR="value"`
52
+ - Referenced with `$VAR`
53
+ - Built-in variables should be capitalized
54
+ - Variables are shared across nested includes
55
+
56
+ ## Includes and Nesting
57
+ - `.include file.inc` - Include other files
58
+ - Supports arbitrary levels of nesting
59
+ - Uses stack-based source management (`@sources`)
60
+ - Variables and functions are preserved through includes
61
+
62
+ ## Plugin System
63
+ - Plugins in `plugin/` directory
64
+ - Imports in `imports/` directory
65
+ - Loaded via `Livetext.customize(mix: "plugin_name")`
66
+ - Plugins can define new dot commands and functions
67
+
68
+ ## Recent Refactoring Changes
69
+ 1. **Eliminated circular dependency**: Merged `Processor` into `Livetext`
70
+ 2. **Fixed double-reading**: Methods now use passed parameters instead of calling `api.body()` again
71
+ 3. **New body raw syntax**: `.def mymeth body raw` for raw body content
72
+ 4. **Updated method signatures**: Explicit parameter declarations
73
+ 5. **Unified processing API**: New `process()` method returns both body and variables
74
+
75
+ ## API Changes-
76
+ - `@parent.body` → `self.body` (in plugins)
77
+ - `live.vars.vars` → `live.variables.to_h` or `live.vars.to_h`
78
+ - `live.xform_file()` → `live.process(file: file)` (recommended)
79
+
80
+ ## Testing
81
+ - Comprehensive test suite in `test/` directory
82
+ - Snapshot tests in `test/snapshots/`
83
+ - Unit tests in `test/unit/`
84
+ - All 154 tests currently passing
85
+ - Plugin testing not yet implemented
86
+
87
+ ## Usage Patterns
88
+ Old pattern:
89
+ ```ruby
90
+ live = Livetext.customize(mix: "plugin", call: ".nopara", vars: vars)
91
+ text = live.xform_file(content_file)
92
+ vars = live.vars.vars
93
+ ```
94
+
95
+ New pattern (recommended):
96
+ ```ruby
97
+ live = Livetext.customize(mix: "plugin", call: ".nopara", vars: vars)
98
+ body, vars = live.process(file: content_file)
99
+ ```
100
+
101
+ ## Key Files
102
+ - `lib/livetext/core.rb` - Main Livetext class
103
+ - `lib/livetext/standard.rb` - Built-in dot commands
104
+ - `lib/livetext/expansion.rb` - Variable/function expansion
105
+ - `lib/livetext/helpers.rb` - Helper methods
106
+ - `lib/livetext/userapi.rb` - User API
107
+ - `test/all.rb` - Test runner
108
+
109
+ ## Known Limitations
110
+ - Not Turing-complete
111
+ - Limited nesting support
112
+ - No branching (if/else)
113
+ - Plugin system needs dedicated testing
114
+
115
+ This summary represents the current state after the major refactoring that eliminated circular dependencies and improved the architecture significantly.
116
+
@@ -0,0 +1,172 @@
1
+ # CodeMirror Integration and Web Test Framework
2
+
3
+ **Date**: 2024-12-19 16:00:00
4
+
5
+ ## CodeMirror Integration
6
+
7
+ ### Overview
8
+ Integrated CodeMirror code editor into the web interface for enhanced post and page editing with LiveText syntax highlighting.
9
+
10
+ ### Files Created/Modified
11
+
12
+ #### `test/manual/codemirror_demo.html`
13
+ - Standalone HTML demo showcasing CodeMirror with custom LiveText syntax highlighting
14
+ - Includes macro toolbar with buttons for common editing tasks
15
+ - Demonstrates LiveText-specific syntax rules (non-terminating markers, bracketed formatting, etc.)
16
+ - Features responsive SVG banner generation and theme switching
17
+
18
+ #### `ui/web/app/assets/livetext_mode.js`
19
+ - Custom CodeMirror mode definition for LiveText syntax
20
+ - Handles LiveText-specific constructs:
21
+ - Variables (`$foo`, `$foo.bar`) - stops at invalid characters
22
+ - Functions (`$$max`, `$$link:param`, `$$index[param]`)
23
+ - Markers (`*`, `_`, `` ` ``, `~`) - non-terminating, space/comma/period terminated
24
+ - Bracketed formatting (`*[bold text]`)
25
+ - Dot commands (`.h1`, `.list`, `.banner`, etc.)
26
+ - Block structures:
27
+ - `.raw`...`__RAW__` (plain text)
28
+ - `.comment`...`.end` (plain text)
29
+ - `.def`/`.func`...`.end` (Ruby code)
30
+ - `.code ruby`/`elixir`/`bash`...`.end` (language-specific highlighting)
31
+
32
+ #### `ui/web/app/views/edit_post.erb`
33
+ - Integrated CodeMirror for post editing
34
+ - Replaces textarea with enhanced editor
35
+ - Includes LiveText syntax highlighting
36
+ - Form submission syncs CodeMirror content back to hidden textarea
37
+
38
+ #### `ui/web/app/views/edit_pages.erb`
39
+ - Integrated CodeMirror for page editing
40
+ - Similar functionality to edit_post.erb
41
+ - Button-triggered save with explicit content syncing
42
+
43
+ #### `ui/web/app/app.rb`
44
+ - Added `/web_assets/*` route to serve CodeMirror assets
45
+ - Fixed post creation workflow to redirect to edit page
46
+ - Enhanced error handling and debugging
47
+
48
+ ### Key Features
49
+ - **Syntax Highlighting**: Custom LiveText mode with accurate tokenization
50
+ - **Macro System**: Toolbar buttons for common editing tasks
51
+ - **Responsive Design**: Adapts to different screen sizes
52
+ - **Theme Support**: Light/dark mode switching
53
+ - **Content Syncing**: Seamless integration with existing form submission
54
+
55
+ ## Web Test Framework
56
+
57
+ ### Overview
58
+ Comprehensive automated testing framework for web interface functionality, covering complete user workflows.
59
+
60
+ ### Files Created
61
+
62
+ #### `test/web_test_helper.rb`
63
+ - Shared helper module for web integration tests
64
+ - Provides methods for:
65
+ - Starting/stopping web server
66
+ - Making HTTP requests (GET, POST)
67
+ - Asserting response types (success, redirect)
68
+ - Managing test repository
69
+ - Silent operation (no debug output)
70
+
71
+ #### `test/web_integration_test.rb`
72
+ - Basic web integration tests
73
+ - Verifies core functionality and test mode
74
+ - Tests repository creation, view management, basic navigation
75
+
76
+ #### `test/web_workflow_test.rb`
77
+ - Comprehensive workflow tests covering:
78
+ - **Post Creation**: Create post via web interface, verify redirect to edit page
79
+ - **Post Editing**: Edit post content, save, verify file content matches
80
+ - **Publish/Unpublish**: Toggle post status, verify API response and HTML display
81
+ - **Delete/Restore**: Delete post (strikethrough), restore (normal display)
82
+ - **Asset Management**: Upload and manage assets
83
+ - **View Configuration**: Configure view settings
84
+ - **Deployment**: Deploy configuration workflow
85
+ - **Error Handling**: Edge cases and error conditions
86
+
87
+ #### `test/web_test_mode_simple_test.rb`
88
+ - Simple test to verify web app test mode functionality
89
+ - Uses curl-based verification of test repository usage
90
+
91
+ ### Test Coverage
92
+
93
+ #### API Level Testing
94
+ - HTTP status codes (200, 302, 303, 404, 500)
95
+ - JSON response validation
96
+ - Redirect behavior verification
97
+ - Error handling and edge cases
98
+
99
+ #### UI Level Testing
100
+ - HTML content verification
101
+ - Visual state changes (published/unpublished status)
102
+ - Strikethrough styling for deleted posts
103
+ - Form submission and content persistence
104
+
105
+ #### Workflow Testing
106
+ - Complete user journeys from start to finish
107
+ - Cross-page navigation and state persistence
108
+ - File system verification (actual file content)
109
+ - Database/metadata verification
110
+
111
+ ### Key Features
112
+ - **Fully Automated**: No manual intervention required
113
+ - **Silent Operation**: No debug output, only errors shown
114
+ - **Comprehensive Coverage**: Tests both API and UI layers
115
+ - **Real File Verification**: Checks actual file content, not just responses
116
+ - **Test Mode Support**: Uses separate test repository (`ui/web/scriptorium-TEST`)
117
+ - **Parallel Safe**: Each test creates fresh test environment
118
+
119
+ ### Integration
120
+ - Added to `test/all` for inclusion in full test suite
121
+ - Follows existing project testing patterns (Minitest)
122
+ - Uses same helper patterns as TUI integration tests
123
+ - Maintains consistency with project coding standards
124
+
125
+ ## Benefits
126
+
127
+ ### CodeMirror Integration
128
+ - Enhanced editing experience with syntax highlighting
129
+ - Reduced editing errors through visual feedback
130
+ - Familiar code editor interface for users
131
+ - Extensible macro system for common tasks
132
+
133
+ ### Web Test Framework
134
+ - Catches regressions in web interface functionality
135
+ - Verifies complete user workflows, not just individual components
136
+ - Provides confidence in web interface reliability
137
+ - Enables safe refactoring and feature additions
138
+ - Documents expected behavior through test cases
139
+
140
+ ## Usage
141
+
142
+ ### Running Web Tests
143
+ ```bash
144
+ # Run all web tests
145
+ ruby test/web_workflow_test.rb
146
+ ruby test/web_integration_test.rb
147
+
148
+ # Run specific test
149
+ ruby test/web_workflow_test.rb -n test_004_post_editing_workflow
150
+
151
+ # Run as part of full test suite
152
+ ruby test/all
153
+ ```
154
+
155
+ ### CodeMirror Demo
156
+ Open `test/manual/codemirror_demo.html` in browser to see LiveText syntax highlighting and macro functionality.
157
+
158
+ ## Technical Notes
159
+
160
+ ### LiveText Syntax Rules
161
+ - Markers are non-terminating (unlike Markdown)
162
+ - Single vs. double markers differ only in termination (space vs. comma/period)
163
+ - Bracketed formatting allows multi-word formatting
164
+ - Variables and functions have specific naming rules
165
+ - Block structures have different body processing rules
166
+
167
+ ### Test Architecture
168
+ - Uses `WebTestHelper` module for shared functionality
169
+ - Each test creates fresh test environment
170
+ - Tests verify both API responses and HTML content
171
+ - File system verification ensures actual persistence
172
+ - Silent operation focuses on genuine errors only
@@ -0,0 +1,126 @@
1
+ # Backup/Restore System Implementation
2
+
3
+ ## Overview
4
+ Implemented a comprehensive backup and restore system for Scriptorium repositories with full/incremental backups, hybrid restore strategies, and 30-day retention.
5
+
6
+ ## Architecture
7
+
8
+ ### Storage Structure
9
+ ```
10
+ repo/backups/
11
+ ├── manifest.txt # Backup registry
12
+ └── data/ # Backup content
13
+ ├── 20250902-120000-full/
14
+ ├── 20250902-130000-incr/
15
+ └── 20250902-140000-incr/
16
+ ```
17
+
18
+ ### Manifest Format
19
+ ```
20
+ 20250902-120000-full Initial full backup
21
+ 20250902-130000-incr Added new post
22
+ 20250902-140000-incr Updated existing post
23
+ ```
24
+
25
+ ### Flat File Structure
26
+ Each backup directory contains files with full relative paths:
27
+ ```
28
+ data/20250902-120000-full/
29
+ ├── posts/0001/source.lt3
30
+ ├── posts/0001/meta.txt
31
+ ├── views/sample/config.txt
32
+ └── config/repo.txt
33
+ ```
34
+
35
+ ## Core Features
36
+
37
+ ### Backup Types
38
+ - **Full Backup**: Complete repository snapshot
39
+ - **Incremental Backup**: Only changed files since last backup
40
+
41
+ ### Change Detection
42
+ - Uses `File.mtime` to identify modified files
43
+ - 1-second sleep before backup creation ensures distinct timestamps
44
+ - Compares file modification times against last backup timestamp
45
+
46
+ ### Restore Strategies
47
+ - **`:safe`** (default): Creates pre-restore backup, then restores
48
+ - **`:merge`**: Overlays backup content on existing files
49
+ - **`:destroy`**: Clears repository and restores from backup
50
+
51
+ ### Dependency Management
52
+ - Always preserves most recent full backup (30-day retention)
53
+ - Restore finds most recent full backup before target
54
+ - Applies all subsequent incremental backups up to target
55
+ - Handles missing dependencies gracefully
56
+
57
+ ## API Methods
58
+
59
+ ### `create_backup(type: :full|:incr, description: nil)`
60
+ - Creates timestamped backup directory
61
+ - Records entry in manifest.txt
62
+ - Handles both full and incremental backups
63
+
64
+ ### `list_backups()`
65
+ - Returns array of backup info: `{timestamp, type, description}`
66
+ - Parses manifest.txt entries
67
+
68
+ ### `restore_backup(timestamp, strategy: :safe)`
69
+ - Implements hybrid restore strategies
70
+ - Finds dependency chain (full + incrementals)
71
+ - Preserves existing files in merge mode
72
+
73
+ ### `delete_backup(timestamp)`
74
+ - Removes backup directory and manifest entry
75
+ - Enforces retention policy (keeps most recent full)
76
+
77
+ ## Key Implementation Details
78
+
79
+ ### Timestamp Precision
80
+ - Uses `Time.now.strftime("%Y%m%d-%H%M%S")` for directory names
81
+ - 1-second sleep before backup creation prevents sub-second conflicts
82
+ - Temporary directory creation + rename ensures atomic operations
83
+
84
+ ### Error Handling
85
+ - Contract system validation (enabled in tests)
86
+ - Graceful handling of missing dependencies
87
+ - Clear error messages for invalid operations
88
+
89
+ ### Test Coverage
90
+ - 16 comprehensive tests covering all scenarios
91
+ - Tests for full/incremental backups, restore strategies, edge cases
92
+ - 100% pass rate with proper contract system integration
93
+
94
+ ## Usage Examples
95
+
96
+ ```ruby
97
+ # Create full backup
98
+ api.create_backup(type: :full, description: "Before major changes")
99
+
100
+ # Create incremental backup
101
+ api.create_backup(type: :incr, description: "Added new post")
102
+
103
+ # List available backups
104
+ backups = api.list_backups
105
+
106
+ # Restore with safe strategy (default)
107
+ api.restore_backup("20250902-120000-full")
108
+
109
+ # Restore with merge strategy
110
+ api.restore_backup("20250902-130000-incr", strategy: :merge)
111
+
112
+ # Delete old backup
113
+ api.delete_backup("20250902-120000-full")
114
+ ```
115
+
116
+ ## Files Modified
117
+ - `lib/scriptorium/api.rb`: Core backup/restore implementation
118
+ - `test/unit/backup_test.rb`: Comprehensive test suite
119
+ - `test/all`: Added backup tests to full test suite
120
+
121
+ ## Status
122
+ ✅ **Complete and Production Ready**
123
+ - All 16 tests passing
124
+ - Full test suite integration
125
+ - Comprehensive error handling
126
+ - 30-day retention policy implemented
@@ -0,0 +1,66 @@
1
+ # Backup Metadata Implementation - 2025-09-07 20:33:39
2
+
3
+ ## Overview
4
+ Added per-backup metadata storage to track version information and backup statistics for better debugging, compatibility checking, and audit trails.
5
+
6
+ ## Changes Made
7
+
8
+ ### 1. Backup Location Change
9
+ - **Changed backup storage location** from `repo/backups/` to `backup-scriptorium/` (parallel to repo)
10
+ - **Test repositories** use `backup-scriptorium-TEST/`
11
+ - **Updated `get_backup_directory()` method** to handle both production and test environments
12
+ - **Made method public** (was private) to allow direct access without `api.send()`
13
+
14
+ ### 2. Per-Backup Metadata File
15
+ - **Added `backup-info.txt`** to each backup directory (both full and incremental)
16
+ - **Contains essential metadata**:
17
+ - Scriptorium version (from `Scriptorium::VERSION`)
18
+ - LiveText version (from `livetext -v` command)
19
+ - Ruby version (from `RUBY_VERSION`)
20
+ - Backup type (full/incremental)
21
+ - Backup name (timestamp-type)
22
+ - Repository path (which repo was backed up)
23
+ - File count (number of files backed up)
24
+ - Total size (backup size in bytes)
25
+ - Platform (OS and Ruby engine)
26
+ - Git commit (first 8 characters, if available)
27
+
28
+ ### 3. Implementation Details
29
+ - **`create_backup_info()` method** - Creates the metadata file
30
+ - **`get_livetext_version()` method** - Gets LiveText version via command line
31
+ - **`get_git_commit_hash()` method** - Gets git commit hash if available
32
+ - **`count_files_in_backup()` method** - Counts files in backup directory
33
+ - **`calculate_directory_size()` method** - Calculates total backup size
34
+ - **Called after backup creation** but before final directory rename
35
+
36
+ ### 4. Test Updates
37
+ - **Added backup info file assertions** to both full and incremental backup tests
38
+ - **Verifies file existence** and content validation
39
+ - **All 16 backup tests pass** with new functionality
40
+
41
+ ## Benefits
42
+ - **Restore validation** - Check compatibility before restoring
43
+ - **Debugging** - Know exactly what versions were used
44
+ - **Migration help** - Understand what needs updating
45
+ - **Audit trail** - Track backup environment over time
46
+ - **Better error diagnosis** - Version mismatch detection
47
+
48
+ ## Files Modified
49
+ - `lib/scriptorium/api.rb` - Added backup metadata functionality
50
+ - `test/unit/backup_test.rb` - Added backup info file tests
51
+
52
+ ## Example Backup Info File
53
+ ```
54
+ # Scriptorium Backup Information
55
+ # Generated: 2025-09-07 20:32:33
56
+ scriptorium_version: 0.6.1
57
+ livetext_version: 0.9.60
58
+ ruby_version: 3.2.3
59
+ backup_type: full
60
+ backup_name: 20250907-203233-full
61
+ repository_path: test/scriptorium-TEST
62
+ file_count: 110
63
+ total_size: 138338
64
+ platform: x86_64-darwin22 ruby
65
+ git_commit: 3b5bcc67
66
+ ```
@@ -0,0 +1,114 @@
1
+ # BannerSVG Configuration Options
2
+
3
+ This document describes all configuration options available for customizing SVG banners using BannerSVG.
4
+
5
+ ---
6
+
7
+ ## Background Options
8
+
9
+ ### `back.color <color>`
10
+ Solid color background.
11
+ - Example: `back.color #FF6B6B`
12
+
13
+ ### `back.linear <start> <end> [direction]`
14
+ Linear gradient background.
15
+ - `start`, `end`: Colors (hex or CSS names)
16
+ - `direction` (optional):
17
+ - `lr` (left-right, default)
18
+ - `tb` (top-bottom)
19
+ - `ul-lr` (upper-left to lower-right)
20
+ - `ll-ur` (lower-left to upper-right)
21
+ - Example: `back.linear #FF6B6B #4ECDC4 lr`
22
+
23
+ ### `back.radial <start> <end> [cx cy r [ar]]`
24
+ Radial gradient background.
25
+ - `start`, `end`: Colors
26
+ - `cx`, `cy`: Center (default: `50% 50%`)
27
+ - `r`: Radius (default: `50%`)
28
+ - `ar`: Aspect ratio compensation (default: `1/aspect` for circular vignette)
29
+ - Example: `back.radial #FF6B6B #4ECDC4 50% 50% 150%`
30
+ - Example with custom aspect: `back.radial #FF6B6B #4ECDC4 75% 25% 60% 0.5`
31
+
32
+ ### `back.image <url>`
33
+ Image background. The image should match the banner's aspect ratio for best results.
34
+ - Example: `back.image /assets/banner.jpg`
35
+
36
+ ---
37
+
38
+ ## Banner Geometry
39
+
40
+ ### `aspect <number>`
41
+ Set the banner's aspect ratio (width/height).
42
+ - Example: `aspect 5.0` (for a 5:1 banner)
43
+
44
+ ---
45
+
46
+ ## Font and Text Options
47
+
48
+ ### `text.font <font-family>`
49
+ Set the font family for both title and subtitle.
50
+ - Example: `text.font Verdana`
51
+
52
+ ### `text.color <color>`
53
+ Set the default text color for both title and subtitle.
54
+ - Example: `text.color #222222`
55
+
56
+ ### `title.color <color>` / `subtitle.color <color>`
57
+ Set the color for title or subtitle individually.
58
+ - Example: `title.color #FF0000`
59
+
60
+ ### `title.scale <number>` / `subtitle.scale <number>`
61
+ Scale the font size for title or subtitle (relative to base size).
62
+ - Example: `title.scale 1.2`
63
+
64
+ ### `title.style <style>` / `subtitle.style <style>`
65
+ Set font style for title or subtitle. Options: `bold`, `italic`, or both.
66
+ - Example: `title.style bold italic`
67
+
68
+ ### `title.align <direction> [x y]` / `subtitle.align <direction> [x y]`
69
+ Align title or subtitle. Directions: `left`, `center`, `right`. Optionally override x/y positions.
70
+ - Example: `title.align center`
71
+ - Example: `subtitle.align right 95% 80%`
72
+
73
+ ### `title.xy <x> <y>` / `subtitle.xy <x> <y>`
74
+ Set explicit x/y coordinates for title or subtitle (overrides align).
75
+ - Example: `title.xy 50% 52%`
76
+
77
+ ### `text.align <direction>`
78
+ Set alignment for both title and subtitle at once.
79
+ - Example: `text.align center`
80
+
81
+ ---
82
+
83
+ ## Advanced/Other Options
84
+
85
+ ### `preserve_aspect <value>`
86
+ Override the SVG's `preserveAspectRatio` attribute. Usually not needed.
87
+ - Example: `preserve_aspect xMidYMid slice`
88
+
89
+ ---
90
+
91
+ ## Example Config
92
+
93
+ ```
94
+ # BannerSVG Example Config
95
+ aspect 5.0
96
+ back.radial #FF6B6B #4ECDC4 50% 50% 150%
97
+ text.font Verdana
98
+ text.color #222222
99
+
100
+ title.color #FFFFFF
101
+ title.scale 1.2
102
+ title.style bold italic
103
+ title.align center
104
+
105
+ title.xy 50% 52%
106
+ subtitle.color #4ECDC4
107
+ subtitle.scale 0.6
108
+ subtitle.style italic
109
+ subtitle.align right 95% 80%
110
+ ```
111
+
112
+ ---
113
+
114
+ For more details or advanced usage, see the code or ask for help!
data/doc/contrib.lt3 ADDED
@@ -0,0 +1,8 @@
1
+ Layout of files and classes
2
+ Conventions and style
3
+ How to...
4
+ - add a dot command
5
+ - add a livetext function
6
+ - create a widget
7
+ - create a theme
8
+ - add tests