ro 4.2.0 → 4.4.0

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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +29 -8
  3. data/LICENSE +1 -1
  4. data/README.md +274 -111
  5. data/Rakefile +2 -2
  6. data/lib/ro/_lib.rb +18 -6
  7. data/lib/ro/asset.rb +23 -13
  8. data/lib/ro/collection.rb +47 -4
  9. data/lib/ro/config.rb +4 -0
  10. data/lib/ro/error.rb +5 -2
  11. data/lib/ro/html.rb +23 -0
  12. data/lib/ro/html_safe.rb +143 -0
  13. data/lib/ro/methods.rb +95 -38
  14. data/lib/ro/node.rb +78 -35
  15. data/lib/ro/path.rb +4 -0
  16. data/lib/ro/template.rb +62 -22
  17. data/lib/ro/text.rb +120 -0
  18. data/lib/ro.rb +4 -0
  19. data/public/api/ro/index-1.json +997 -79
  20. data/public/api/ro/index.json +997 -79
  21. data/public/api/ro/nerd/fastest-possible-embeddings/index.json +90 -0
  22. data/public/api/ro/nerd/ima/index.json +49 -0
  23. data/public/api/ro/nerd/index/index.json +74 -0
  24. data/public/api/ro/nerd/index-1.json +204 -0
  25. data/public/api/ro/nerd/index.json +194 -0
  26. data/public/api/ro/pages/about/index.json +60 -0
  27. data/public/api/ro/pages/contact/index.json +50 -0
  28. data/public/api/ro/pages/cv/index.json +49 -0
  29. data/public/api/ro/pages/disco/index.json +117 -0
  30. data/public/api/ro/pages/index/index.json +30 -0
  31. data/public/api/ro/pages/index-1.json +366 -0
  32. data/public/api/ro/pages/index.json +356 -0
  33. data/public/api/ro/pages/jess/index.json +62 -0
  34. data/public/api/ro/pages/now/index.json +43 -0
  35. data/public/api/ro/posts/almost-died-in-an-ice-cave/index.json +265 -0
  36. data/public/api/ro/posts/facebook-and-global-extremism/index.json +90 -0
  37. data/public/api/ro/posts/index-1.json +461 -79
  38. data/public/api/ro/posts/index.json +461 -79
  39. data/public/api/ro/posts/lemmings-considered-harmful/index.json +49 -0
  40. data/public/api/ro/posts/lost-in-the-desert/index.json +49 -0
  41. data/public/api/ro/posts/mission/index.json +49 -0
  42. data/public/api/ro/posts/return-your-laptop/index.json +61 -0
  43. data/public/ro/nerd/fastest-possible-embeddings/assets/giraffe.jpeg +0 -0
  44. data/public/ro/nerd/fastest-possible-embeddings/assets/let-me-in.jpg +0 -0
  45. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.js +70 -0
  46. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.rs +68 -0
  47. data/public/ro/nerd/fastest-possible-embeddings/assets/terminal.jpg +0 -0
  48. data/public/ro/nerd/fastest-possible-embeddings/attributes.yml +7 -0
  49. data/public/ro/nerd/fastest-possible-embeddings/body.md +266 -0
  50. data/public/ro/nerd/ima/assets/og.jpeg +0 -0
  51. data/public/ro/nerd/ima/attributes.yml +8 -0
  52. data/public/ro/nerd/ima/body.md +22 -0
  53. data/public/ro/nerd/index/assets/giraffe.jpeg +0 -0
  54. data/public/ro/nerd/index/assets/let-me-in.jpg +0 -0
  55. data/public/ro/nerd/index/assets/terminal.jpg +0 -0
  56. data/public/ro/nerd/index/attributes.yml +7 -0
  57. data/public/ro/nerd/index/body.md +130 -0
  58. data/public/ro/pages/about/assets/og.jpeg +0 -0
  59. data/public/ro/pages/about/assets/speak-english-pulp-fiction.gif +0 -0
  60. data/public/ro/pages/about/body.md +40 -0
  61. data/public/ro/pages/contact/assets/giraffe.jpeg +0 -0
  62. data/public/ro/pages/contact/attributes.yml +7 -0
  63. data/public/ro/pages/contact/body.md +9 -0
  64. data/public/ro/pages/cv/assets/ara.jpg +0 -0
  65. data/public/ro/pages/cv/attributes.yml +6 -0
  66. data/public/ro/pages/cv/body.md +122 -0
  67. data/public/ro/pages/disco/assets/disco.jpg +0 -0
  68. data/public/ro/pages/disco/assets/disco.png +0 -0
  69. data/public/ro/pages/disco/assets/speak-english-pulp-fiction.gif +0 -0
  70. data/public/ro/pages/disco/assets/src/environment.md +2354 -0
  71. data/public/ro/pages/disco/assets/src/fortune-500.md +2518 -0
  72. data/public/ro/pages/disco/assets/src/greed.md +2703 -0
  73. data/public/ro/pages/disco/assets/src/up-at-night.md +2337 -0
  74. data/public/ro/pages/disco/attributes.yml +9 -0
  75. data/public/ro/pages/disco/body.md +99 -0
  76. data/public/ro/pages/disco/samples/environment.md +2354 -0
  77. data/public/ro/pages/disco/samples/fortune-500.md +2518 -0
  78. data/public/ro/pages/disco/samples/greed.md +2703 -0
  79. data/public/ro/pages/disco/samples/up-at-night.md +2337 -0
  80. data/public/ro/pages/index/attributes.yml +1 -0
  81. data/public/ro/pages/index/body.md +15 -0
  82. data/public/ro/pages/jess/assets/og.jpg +0 -0
  83. data/public/ro/pages/jess/assets/speak-english-pulp-fiction.gif +0 -0
  84. data/public/ro/pages/jess/attributes.yml +7 -0
  85. data/public/ro/pages/jess/body.md +3 -0
  86. data/public/ro/pages/now/assets/speak-english-pulp-fiction.gif +0 -0
  87. data/public/ro/pages/now/attributes.yml +1 -0
  88. data/public/ro/pages/now/body.md +24 -0
  89. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image1.png +0 -0
  90. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image10.png +0 -0
  91. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image11.png +0 -0
  92. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image12.png +0 -0
  93. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image13.png +0 -0
  94. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image14.png +0 -0
  95. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image15.png +0 -0
  96. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image2.png +0 -0
  97. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image3.png +0 -0
  98. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image4.png +0 -0
  99. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image5.png +0 -0
  100. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image6.png +0 -0
  101. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image7.png +0 -0
  102. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image8.png +0 -0
  103. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image9.png +0 -0
  104. data/public/ro/posts/almost-died-in-an-ice-cave/assets/josh-pointing.jpg +0 -0
  105. data/public/ro/posts/almost-died-in-an-ice-cave/assets/levi-rawr.png +0 -0
  106. data/public/ro/posts/almost-died-in-an-ice-cave/assets/og.jpg +0 -0
  107. data/public/ro/posts/almost-died-in-an-ice-cave/assets/purple-heart.jpg +0 -0
  108. data/public/ro/posts/almost-died-in-an-ice-cave/attributes.yml +6 -0
  109. data/public/ro/posts/almost-died-in-an-ice-cave/body.md +419 -0
  110. data/public/ro/posts/facebook-and-global-extremism/assets/background.html +125 -0
  111. data/public/ro/posts/facebook-and-global-extremism/assets/background.md +95 -0
  112. data/public/ro/posts/facebook-and-global-extremism/assets/og.jpg +0 -0
  113. data/public/ro/posts/facebook-and-global-extremism/assets/prompt.txt +122 -0
  114. data/public/ro/posts/facebook-and-global-extremism/assets/results.md +183 -0
  115. data/public/ro/posts/facebook-and-global-extremism/assets/survey.txt +190 -0
  116. data/public/ro/posts/facebook-and-global-extremism/attributes.yml +7 -0
  117. data/public/ro/posts/facebook-and-global-extremism/body.md +393 -0
  118. data/public/ro/posts/lemmings-considered-harmful/assets/lemming.jpeg +0 -0
  119. data/public/ro/posts/lemmings-considered-harmful/attributes.yml +6 -0
  120. data/public/ro/posts/lemmings-considered-harmful/body.md +43 -0
  121. data/public/ro/posts/lost-in-the-desert/assets/og.jpg +0 -0
  122. data/public/ro/posts/lost-in-the-desert/attributes.yml +6 -0
  123. data/public/ro/posts/lost-in-the-desert/body.md +7 -0
  124. data/public/ro/posts/mission/assets/og.jpg +0 -0
  125. data/public/ro/posts/mission/attributes.yml +6 -0
  126. data/public/ro/posts/mission/body.md +4 -0
  127. data/public/ro/posts/return-your-laptop/assets/og.jpg +0 -0
  128. data/public/ro/posts/return-your-laptop/assets/return-your-laptop.png +0 -0
  129. data/public/ro/posts/return-your-laptop/attributes.yml +6 -0
  130. data/public/ro/posts/return-your-laptop/body.md +58 -0
  131. data/ro.gemspec +178 -49
  132. data/scripts/speedtest.rb +324 -0
  133. data/tmp/gem-details.oe +0 -0
  134. metadata +157 -33
  135. data/public/api/ro/posts/first_post/index.json +0 -52
  136. data/public/api/ro/posts/second_post/index.json +0 -51
  137. data/public/api/ro/posts/third_post/index.json +0 -51
  138. data/public/ro/posts/first_post/assets/foo/bar/baz.jpg +0 -0
  139. data/public/ro/posts/first_post/assets/foo.jpg +0 -0
  140. data/public/ro/posts/first_post/assets/src/foo/bar.rb +0 -3
  141. data/public/ro/posts/first_post/attributes.yml +0 -2
  142. data/public/ro/posts/first_post/blurb.erb.md +0 -7
  143. data/public/ro/posts/first_post/body.md +0 -16
  144. data/public/ro/posts/first_post/testing.txt +0 -3
  145. data/public/ro/posts/second_post/assets/foo/bar/baz.jpg +0 -0
  146. data/public/ro/posts/second_post/assets/foo.jpg +0 -0
  147. data/public/ro/posts/second_post/assets/src/foo/bar.rb +0 -3
  148. data/public/ro/posts/second_post/attributes.yml +0 -2
  149. data/public/ro/posts/second_post/blurb.erb.md +0 -5
  150. data/public/ro/posts/second_post/body.md +0 -16
  151. data/public/ro/posts/third_post/assets/foo/bar/baz.jpg +0 -0
  152. data/public/ro/posts/third_post/assets/foo.jpg +0 -0
  153. data/public/ro/posts/third_post/assets/src/foo/bar.rb +0 -3
  154. data/public/ro/posts/third_post/attributes.yml +0 -2
  155. data/public/ro/posts/third_post/blurb.erb.md +0 -5
  156. data/public/ro/posts/third_post/body.md +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50e5d272b2bdbfe25f9ae109ed44568e71637820c4768ea772e757c7436c38cc
4
- data.tar.gz: 84372b1f2cc28f316ed1eff63c0ce6ec4333f18a886a0cc38f4c86617baa0c0a
3
+ metadata.gz: 9b56a7cf51b2b6e2140b3be71875fe284e77a59d0e7fa108fd45d39369aba51b
4
+ data.tar.gz: 02da6783adba57026d22c2e95841ad3b3acc4979c538bd86896b7f293037178b
5
5
  SHA512:
6
- metadata.gz: e92b12b8067606b5b5ee11a3db65c926e492298aa3bed178459550d578a6b493762acbc3424fc0e2ac259d84d45cab1a69bc5e07e3550e58cbbdd14b18078c11
7
- data.tar.gz: 7a587649abd8cb3a79e667d4767b33005a47a860983725546acdae8f97dfadaafe140f49fda93a12000097171ed4aba7fea5507467bd480b9b83496115aa3352
6
+ metadata.gz: b704d4f58a18df10308884c353dc05293d294d46ddfb46b8241e5047691500dcf5471f5dac5522a8126e59885c61b49fd03deba036e54db6f2191145706f0450
7
+ data.tar.gz: 3bcf32a9c1096c33c898b582f4d038625771c44203ce49792017d07b097285327ce6e90f0c3136bfdda1e185c0d826a50eefbf377dfd2e6e9fc126b8bfed80bf
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ro (2.0.0)
4
+ ro (4.2.1)
5
5
  ak47 (~> 0.2)
6
+ image_size (~> 3.0)
6
7
  kramdown (~> 2.4, >= 2.4.0)
7
8
  kramdown-parser-gfm (~> 1.1, >= 1.1.0)
8
9
  map (~> 6.6, >= 6.6.0)
@@ -16,28 +17,48 @@ GEM
16
17
  guard (~> 0.10.0)
17
18
  shell_tools (~> 0.1.0)
18
19
  smart_colored
19
- ffi (1.16.3)
20
+ ffi (1.17.0)
21
+ ffi (1.17.0-aarch64-linux-gnu)
22
+ ffi (1.17.0-aarch64-linux-musl)
23
+ ffi (1.17.0-arm-linux-gnu)
24
+ ffi (1.17.0-arm-linux-musl)
25
+ ffi (1.17.0-arm64-darwin)
26
+ ffi (1.17.0-x86-linux-gnu)
27
+ ffi (1.17.0-x86-linux-musl)
28
+ ffi (1.17.0-x86_64-darwin)
29
+ ffi (1.17.0-x86_64-linux-gnu)
30
+ ffi (1.17.0-x86_64-linux-musl)
20
31
  guard (0.10.0)
21
32
  ffi (>= 0.5.0)
22
33
  thor (~> 0.14.6)
34
+ image_size (3.4.0)
23
35
  kramdown (2.4.0)
24
36
  rexml
25
37
  kramdown-parser-gfm (1.1.0)
26
38
  kramdown (~> 2.0)
27
39
  map (6.6.0)
28
- rexml (3.2.6)
29
- rouge (4.1.1)
40
+ rexml (3.3.9)
41
+ rouge (4.4.0)
30
42
  shell_tools (0.1.2)
31
43
  smart_colored (1.1.1)
32
44
  thor (0.14.6)
33
- webrick (1.8.1)
45
+ webrick (1.8.2)
34
46
 
35
47
  PLATFORMS
36
- arm64-darwin-21
37
- x86_64-linux
48
+ aarch64-linux-gnu
49
+ aarch64-linux-musl
50
+ arm-linux-gnu
51
+ arm-linux-musl
52
+ arm64-darwin
53
+ ruby
54
+ x86-linux-gnu
55
+ x86-linux-musl
56
+ x86_64-darwin
57
+ x86_64-linux-gnu
58
+ x86_64-linux-musl
38
59
 
39
60
  DEPENDENCIES
40
61
  ro!
41
62
 
42
63
  BUNDLED WITH
43
- 2.4.22
64
+ 2.5.22
data/LICENSE CHANGED
@@ -1 +1 @@
1
- Ruby
1
+ Nonstandard
data/README.md CHANGED
@@ -1,178 +1,341 @@
1
- NAME
2
- ====
1
+ TL;DR:
2
+ ------
3
3
 
4
- `ro`
4
+ `ro` stands for `read only`, and it is the tiniest, best, headless cms.
5
5
 
6
- INSTALL
7
- =======
6
+ it lets you keep all your content in github, as god intended.
7
+
8
+ it is one part cms, one part database, one part api, and one part magic.
9
+
10
+ if you used a headless cms, it's like that, before they existed, except way better, and free.
11
+
12
+ with `ro`, you can seperate your content from presentation, like a sane and decent human being.
13
+
14
+ > silent code whispers
15
+ > github's gentle, peaceful hush
16
+ > simplicity reigns
17
+
18
+ README
19
+ ------
20
+
21
+ `ro` is has been in professional, production use for over a decade, powering
22
+ many, many websites built by http://dojo4.com, and others.
23
+
24
+ from static sites, to rails monoliths, to simple ruby sites, to javascript
25
+ sites built on next.js, `ro` is the portable, simple, future-proof content
26
+ system you always dreamed about then started to write but found out the web is
27
+ a mess.
28
+
29
+ with `ro`, your shit will be *clean*.
30
+
31
+ ---
32
+
33
+ to grok `ro` it is best to start with an example of some real content,
34
+ for a real site.
8
35
 
9
- as a gem
10
36
 
11
37
  ```sh
12
- ~> gem install ro
38
+
39
+ drawohara@drawohara.dev:ro[main] #=> tree public/ro/posts/almost-died-in-an-ice-cave/
40
+ public/ro/posts/almost-died-in-an-ice-cave/
41
+ ├── assets
42
+ │ ├── image1.png
43
+ │ ├── image2.png
44
+ │ ├── image3.png
45
+ │ ├── og.jpg
46
+ │ └── purple-heart.jpg
47
+ ├── attributes.yml
48
+ └── body.md
49
+
13
50
  ```
14
51
 
52
+ in this example you can see a few things, regarding the layout of a `ro` directory:
53
+
54
+ - `ro` content often, but is not required, to live in `public`. more on this below.
15
55
 
16
- SYNOPSIS
17
- ========
56
+ - the essential layout is
18
57
 
19
- keep all your content in git as god intended.
58
+ ```ruby
20
59
 
21
- even images.
60
+ @root = "ro"
61
+ @collection = "posts"
62
+ @id = "almost-died-in-an-ice-cave"
22
63
 
23
- fuck wordpress.
64
+ "#{ @root }/#{ @collection }/#{ @id }"
24
65
 
25
- # TL;DR;
66
+ ```
26
67
 
27
- `ro` is the world's tiniest, simplest, zero-config, and most bestest headless CMS.
68
+ if you learn best by example, you can examine the `ro` directory of my own website here -> https://github.com/ahoward/drawohara.io/tree/main/public/ro
28
69
 
29
- it keeps your content in an on disk bundle that will make sense to an 11 year
70
+ - several environment variables control how `ro` works, most notably
30
71
 
31
- it depends on nothing but GitHub itself for the storage, management, and
32
- delivery of rich web content and assets.
72
+ ```ruby
33
73
 
34
- ## Storage
74
+ # this is the fs root of all ro content
75
+ #
35
76
 
36
- `ro` keeps your structured web content in a super sane structure, that keeps
37
- assets close to its related content, allows for structured data to be kept
38
- along side markdown/html content, and which supports source code as a first
39
- class citizen.
77
+ Ro.root = ENV['RO_ROOT'] || './public/ro'
40
78
 
41
- For example, given:
79
+ # this is the url where ro content, especially images, will be expected to
80
+ # live at when live
81
+
82
+ Ro.url = ENV['RO_URL'] || '/ro'
42
83
 
43
- ```sh
44
- ~> tree ro/data
45
-
46
- # ro/data
47
- # └── posts
48
- # ├── first-post
49
- # │   ├── attributes.yml
50
- # │   └── body.md
51
- # │   ├── blurb.erb.md
52
- # │   ├── assets
53
- # │   │   ├── foo.jpg
54
84
  ```
55
85
 
56
- `ro` will provide an interface logically consistent with:
86
+ more about this can be rtfm'd here -> https://github.com/ahoward/ro/blob/main/lib/ro.rb#L29-L55
87
+
88
+ because not having a repl sucks, so `ro` has one. you should too.
89
+
90
+ ```sh
91
+
92
+ # fire up the KONSOULLLLL!
93
+
94
+ ~> ro console ./public/ro/
95
+
96
+ ```
57
97
 
58
98
  ```ruby
59
- node.attributes #=> any/all the data loaded from 'attributes.yml'
60
- node.attributes.body #=> an HTML representation of 'body.md'
61
- node.attributes.blurb #=> an HTML representation of 'blurb.md'
62
- node.attributes.assets #=> list of assets with url and path info
99
+
100
+ ro.posts.almost_died_in_an_ice_cave.attributes.keys #=>
101
+
102
+ ["og", "body", "assets", "_meta"]
103
+
104
+ ro.posts.almost_died_in_an_ice_cave.attributes.og #=>
105
+
106
+ {"image"=>{"url"=>"/ro/posts/almost-died-in-an-ice-cave/assets/og.jpg"},
107
+ "title"=>"Almost Died In An Ice Cave",
108
+ "description"=>"On April of 2024, I, along with 6 of my friends, dug for our lives to come out on the other side."}
109
+
110
+ ro.posts.almost_died_in_an_ice_cave.attributes.body.slice(0,420) #=>
111
+
112
+ "<div class=\"ro markdown\">\n <p><a href=\"#tl;dr;\">tl;dr;</a></p>\n\n<blockquote>\n <p>in april, 2024, myself, and 6 brave men attempted to cross the harding\nicefield.</p>\n\n <p>in celebration of <a href=\"https://en.wikipedia.org/wiki/Harding_Icefield#History\">yule kilcher’s 1968 crossing</a></p>\n\n <p>midway through our trip, at the point of no return, we were beseiged by a storm of storms.</p>\n\n <p>we dug shoulder to "
113
+
114
+ ro.posts.almost_died_in_an_ice_cave.assets.first #=>
115
+
116
+ "public/ro/posts/almost-died-in-an-ice-cave/assets/image1.png"
117
+
118
+ ro.posts.almost_died_in_an_ice_cave.assets.first.url #=>
119
+
120
+ "/ro/posts/almost-died-in-an-ice-cave/assets/image1.png"
121
+
122
+
63
123
  ```
64
124
 
65
- To learn more, clone this repo, `bundle install`, and fire up a console to
66
- check play with this idea:
125
+ __boom__ // **now we're cooking with gas!**
67
126
 
68
- eg: [given this node](https://github.com/ahoward/ro/tree/main/ro/data/posts/first-post)
127
+ serveral things will be obvious to the non-ai enabled observer:
69
128
 
70
- ```ruby
71
- ~> ro console
129
+ - every node has a hash of attributes
130
+ - 'file' attributes are *rendered* based on file type
131
+ - assets in rendered content are __url aware__
132
+
133
+ you can see the list of file types `ro` supports here -> https://github.com/ahoward/ro/blob/main/lib/ro/template.rb#L43-L63
134
+
135
+ if you can't build a website with just these...
136
+
137
+ 🙊 [you've come to the wrong place!](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExd2NpbmsxMHRxNnRsNjFzNWczN2JtejE5aXc0YXA3MHV3a3pwb3hodyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/vDlw1tKNwx40BGbWcQ/giphy.gif)
72
138
 
73
- ro[./ro/data]:001:0> ro.posts.first_post.title
74
- => "First Post"
139
+ ---
140
+ now, about that rendering process...
75
141
 
76
- ro[./ro/data]:002:0> ro.collections.posts.first_post.assets.first.url
77
- => "/ro/posts/first-post/assets/foo.jpg"
142
+ for any 'html-ish' type, links to relative assets, will be expanded such that
143
+ images will be resolved to thier final deployment destination.
144
+
145
+ eg. given __ro/posts/foo-bar/body.md__ containing the markdown
146
+
147
+ ```markdown
148
+
149
+ [linky](./assets/report.pdf)
150
+
151
+ ![alty](./assets/pretty.png)
78
152
 
79
- ro[./ro/data]:003:0> ro.collections.posts.first_post.body.slice(0,42)
80
- => "<div class='ro markdown'>\n <ul>\n <li>one"
81
153
  ```
82
154
 
155
+ you will end up with html that looks like so:
83
156
 
84
- ## Management
157
+ ```html
85
158
 
86
- Managing `ro` is as simple as using the built-in GitHub Markdown editor. The
87
- file system layout, which supports relative asset urls, means the built-in
88
- editor preview renders just fine. Of course, you are free to manage content
89
- programatically as well. Either way, updates to the the content will result
90
- in an automated API build of a static API which is then deployed to GitHub
91
- Pages.
159
+ <a href='/ro/posts/foo-bar/assets/report.pdf'>linky</a>
92
160
 
93
- This is made possible by certain design decisions `ro` has made, specifically
94
- allowing assets/ to be stored and rendered relative to their parent content.
161
+ <img src='/ro/posts/foo-bar/assets/pretty.png'>alty</a>
95
162
 
96
- Of course, you have all the power of `git` so other methods of managing the
97
- content are available, programtic, locally in vs-code, etc. You have lots of
98
- simply options, none of which require drivers or databases, and all of which
99
- provide perfect history over your valuable web content and assets.
100
163
 
101
- A word on managing assets, if you plan to have many large images, you probably
102
- want to enable GitLFS on your content repository, `ro` plays perfectly with
103
- it.
164
+ ```
104
165
 
166
+ ---
167
+ __OH MAN THAT SUX I DO NOT WANT MY IMAGES STORED IN GH!!!!__
105
168
 
106
- ## Delivery
169
+ *sit down... breathe...*
107
170
 
108
- Delivery of `ro` content, to remote clients, is via http+json. To output your
109
- content as json, you simply need to run
171
+ and enable [git-lfs](https://git-lfs.com/)
110
172
 
111
- ```sh
112
- ~> ro build
113
-
114
- ro.build: public/ro -> public/api/ro
115
- ro.build: public/api/ro/posts/first_post/index.json
116
- ro.build: public/api/ro/posts/second_post/index.json
117
- ro.build: public/api/ro/posts/third_post/index.json
118
- ro.build: public/api/ro/posts/index/0.json
119
- ro.build: public/api/ro/posts/index.json
120
- ro.build: public/api/ro/index/0.json
121
- ro.build: public/api/ro/index.json
122
- ro.build: public/api/ro/index.html
123
- ro.build: public/ro -> public/api/ro in 0.08s
173
+ it used to be fragile but, since everyone the in the world is now checking in massive jupyter notebooks it 'just works'
174
+
175
+ ---
176
+ now, recall what we said about `public` and `RO_URL`? by default, this is is `/ro`...
177
+
178
+ therefore, if we have:
179
+
180
+ `./public/ro/posts/foobar/...'
181
+
182
+ paths found under `public` are going to start with `/ro`...
183
+
184
+ > are you tracking yet?
124
185
 
186
+ also, if you do not host your `ro` directory under public (but why not? it
187
+ *is* public content after all..), then you will need to set `RO_URL` to be the
188
+ ultimate destination of your image deployment. this can be cloudinary, s3,
189
+ whatever. it just needs to be the url prefix to whack in front of relative
190
+ image urls.
191
+
192
+ note - not only html has this 'expansion' applied, relative assets in your
193
+ attributes will be expanded too, at any depth. eg. -> https://github.com/ahoward/ro/blob/main/lib/ro/methods.rb#L233-L260
194
+
195
+ this means code like this:
196
+
197
+ ```yaml
198
+ # file: public/ro/posts/foo-bar/attributes.yml
199
+
200
+ og:
201
+ image: ./assets/og.jpg
125
202
  ```
126
203
 
127
- During the build, assets are expanded to be the full URL of the final
128
- deployment destination. This is done via the RO_URL environment variable, and
129
- automatically with a pre-build GitHub Action that will deploy your content via
130
- GitHub Pages. See
131
- https://github.com/ahoward/ro/blob/main/.github/workflows/gh-pages.yml#L55 for
132
- more details.
204
+ will 'just work'. of course, this assumes that 'public/ro/foo-bar/assets/og.jpg' exists!
205
+
206
+ the code is rather robust here, and is not a simple string bashing approach.
207
+
208
+ it's tight, and you can trust it.
133
209
 
134
- You can view sample output from this Action, deployed to GH Pages here: https://ahoward.github.io/ro
210
+ ---
211
+ a bit about markdown...
135
212
 
213
+ markdown is. the web. also AI, but i digress... if you aren't writing in
214
+ markdown, you are probably writing `perl`... (nothing wrong with that btw!)
136
215
 
216
+ but markdown has a lot of edge cases, not least of which syntax highlighting
217
+ and bs css to deal with.
137
218
 
138
- # USAGE
219
+ `ro`, again, 'just works' here.
139
220
 
140
- #### WRITE-ME // #TODO
221
+ - it uses github flavored markdown (gfm), extracts front-matter and folds it
222
+ into `attributes`, auto-links stuff (gfm does not), and inlines the css
223
+ styles for speed and so you don't have to eff with the css to render src
224
+ code all pretty. see https://github.com/ahoward/ro/blob/main/lib/ro/template.rb#L117-L143
141
225
 
142
- ## API // Javascript
226
+ - you can set the gfm theme via the `RO_MD_THEME` ENV var. this supports
227
+ anything [rouge](https://github.com/rouge-ruby/rouge) does.
143
228
 
144
- #### WRITE-ME // #TODO
145
229
 
146
- ## CLI
230
+ ---
231
+ > __I HATE RUBY!!!! RAWR__
147
232
 
148
- #### WRITE-ME // #TODO
233
+ whatever. use javascript. `ro` is also a 'static cms api builder`.
149
234
 
150
- ## Programatic // Ruby
235
+ *WUT*?
151
236
 
152
- #### WRITE-ME // #TODO
237
+ it can compile your entire content db into a static api of js, designed to be
238
+ ultra, ultra, ultra easy to consume. no stupid graphql thing, no bullsxxx
239
+ api_key, no vendor lock-in to prismic, dato, contentful, or some other
240
+ extorsionist regime., just a lil `fetch` and you are __GTG BRO!__
153
241
 
154
- ## Via Repository
242
+ you don't even have to render the stuff, it's pre-rendered html in the api ready to `dangerouslySetInnerHTM`!
155
243
 
156
- #### WRITE-ME // #TODO
244
+ __(alsoCamelCaseMakeAPIHARDToReadWithEMPHASIS)__
157
245
 
158
- - note on http vs https
246
+ you can see an example here -> https://github.com/ahoward/ro/tree/main/public/api/ro
247
+
248
+ i won't explain more now except to say that all you need to do to make a js
249
+ bundle is
159
250
 
160
- SAMPLES
161
- =======
162
- #### <========< [samples/a.rb](https://github.com/ahoward/ro/blob/main/samples/a.rb) >========>
163
251
  ```sh
164
- ~ > cat samples/a.rb
252
+
253
+ ~> ro build
254
+
165
255
  ```
256
+
257
+ and then look carefully, it makes it easy to 'grab everything stupid style' or
258
+ to paginate client side. each collection has a `index.js` with everything, a
259
+ `index-$pageno.js` with details about the next page, iff any, and of course, it
260
+ produces an `index.json` file, complete with those gnarly *width* and *height*
261
+ numbers you need to *fight FUOC* and layout shift.
262
+
263
+ if you don't know what that means, probably use [wordpress](https://drawohara.io/dojo4/archive/irish-dance-and-wordpress-the-soul-destroyer/)
264
+
265
+ lil detail about that link^, it is from *10 years ago*, when dojo4 was still running, and running on `ro`.
266
+
267
+ ---
268
+
269
+ one super comman pattern, is to add a build step to a github workflow, and
270
+ then publish the js api via gh-pages. see an example here:
271
+
272
+ https://github.com/ahoward/ro/blob/main/.github/workflows/gh-pages.yml
273
+
274
+ __WUT!?!?!___
275
+
276
+ - your content is in github
277
+ - you want to consume it in js
278
+ - add a build step to build the js api and deploy it via gh-pages
279
+ - consume that 'static cms api' via fetch
280
+
281
+ *free*, image ready, headless CMS. yep.
282
+
283
+ ... 🤯🤯🤯
284
+
285
+ ---
286
+
287
+ finally, and, truly, this is possibly the *coup de grâce*, you can just
288
+ friggin use github as your CMS now! why? because the markdown previw on
289
+ gh... just works. 🤤
290
+
291
+ eg. https://github.com/ahoward/ro/blob/main/public/ro/posts/almost-died-in-an-ice-cave/body.md
292
+
293
+ ADVANCED
294
+ ---------
295
+
296
+ - include the public directory in your gh-pages, pull that shit through
297
+ cloudinary/imgix/etc as the img src... responsive images, with client side
298
+ processing. zero work.
299
+
300
+ - use ro in your rails app/models with the `active_model` adapter.
301
+ https://github.com/ahoward/ro/blob/main/lib/ro/model.rb , it supports
302
+ pagination and all the things. rails ready.
303
+
304
+ - explore built-in support for syntax highlighted source code. just put a
305
+ file in ./assets/src/a.rb and it 'just works'
306
+
307
+ - explore the api in the repl, you'll find POLS stuff like
308
+
166
309
  ```ruby
167
- require 'ro'
168
-
169
- p 42
310
+
311
+ ro.get('posts').get('almost-died-in-an-ice-cave')
312
+
313
+ ro.get('posts/almost-died-in-an-ice-cave')
314
+
315
+ ro.get('posts').get('almost-died-in-an-ice-cave').assets.first.img
316
+
317
+ #=> {:format=>"png", :width=>1456, :height=>817}
318
+
170
319
  ```
171
320
 
321
+ DOCS
322
+ ----
323
+ 1) vibe it AI
324
+ 2) RTFC
325
+
326
+ BORING SHIT
327
+ -----------
328
+
172
329
  ```sh
173
- ~ > ruby samples/a.rb
174
- ```
175
- ```txt
176
- 42
330
+
331
+ ~> gem install ro
332
+
177
333
  ```
178
334
 
335
+ LICENSE
336
+ -------
337
+ https://github.com/LGUG2Z/komorebi-license
338
+
339
+ AI
340
+ --
341
+ suck it 🤖s!
data/Rakefile CHANGED
@@ -312,8 +312,8 @@ BEGIN {
312
312
  This.version = This.object.version
313
313
  This.dependencies = This.object.dependencies
314
314
  This.summary = This.object.summary
315
- This.description = This.respond_to?(:description) ? This.description : This.summary
316
- This.license = This.respond_to?(:license) ? This.license : IO.binread('LICENSE').strip
315
+ This.description = This.object.respond_to?(:description) ? This.object.description : This.summary
316
+ This.license = This.object.respond_to?(:license) ? This.object.license : IO.binread('LICENSE').strip
317
317
 
318
318
  # discover full path to this ruby executable
319
319
  #
data/lib/ro/_lib.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Ro
2
- VERSION = '4.2.0' unless defined?(VERSION)
2
+ VERSION = '4.4.0' unless defined?(VERSION)
3
3
 
4
4
  class << self
5
5
  def version
@@ -28,7 +28,7 @@ module Ro
28
28
 
29
29
  def libs
30
30
  %w[
31
- fileutils pathname yaml json logger erb cgi rexml time date thread
31
+ fileutils pathname yaml json logger erb cgi uri time date thread securerandom
32
32
  ]
33
33
  end
34
34
 
@@ -46,11 +46,23 @@ module Ro
46
46
  'rouge' =>
47
47
  ['rouge', '~> 4.1', ' >= 4.1.1'],
48
48
 
49
- 'ak47' =>
50
- ['ak47', '~> 0.2'],
49
+ 'front_matter_parser' =>
50
+ ['front_matter_parser', '~> 1.0'],
51
51
 
52
- 'webrick' =>
53
- ['webrick', '~> 1.8.1'],
52
+ 'rinku' =>
53
+ ['rinku', '~> 2.0'],
54
+
55
+ #'ak47' =>
56
+ #['ak47', '~> 0.2'],
57
+
58
+ #'webrick' =>
59
+ #['webrick', '~> 1.9.1'],
60
+
61
+ 'image_size' =>
62
+ ['image_size', '~> 3.4'],
63
+
64
+ 'nokogiri' =>
65
+ ['nokogiri', '~> 1'],
54
66
  }
55
67
  end
56
68
 
data/lib/ro/asset.rb CHANGED
@@ -2,14 +2,6 @@ module Ro
2
2
  class Asset < ::String
3
3
  include Klass
4
4
 
5
- DEFAULT_IMAGE_PATTERNS = [
6
- /[.](webp|jpg|jpeg|png|gif|tif|tiff|svg)$/i
7
- ]
8
-
9
- def Asset.image_patterns
10
- @image_patterns ||= DEFAULT_IMAGE_PATTERNS.dup
11
- end
12
-
13
5
  attr_reader :path, :node, :relative_path, :name, :url
14
6
 
15
7
  def initialize(arg, *args)
@@ -28,18 +20,36 @@ module Ro
28
20
  super(@path)
29
21
  end
30
22
 
31
- def image?
32
- @path.file? && Asset.image_patterns.any? { |pattern| pattern === @path.basename }
23
+ def is_img?
24
+ @path.file? && Ro.is_image?(@path.basename)
33
25
  end
34
26
 
35
- def src
27
+ alias is_img is_img?
28
+
29
+ def img
30
+ return unless is_img?
31
+ Ro.image_info(path.to_s)
32
+ end
33
+
34
+ def is_src?
36
35
  key = relative_path.parts
37
36
  subdir = key.size > 2 ? key[1] : nil
38
- is_src = subdir == 'src'
37
+ !!(subdir == 'src')
38
+ end
39
39
 
40
- return unless is_src
40
+ alias is_src is_src?
41
41
 
42
+ def src
43
+ return unless is_src?
42
44
  Ro.render_src(path, node)
43
45
  end
46
+
47
+ def stat
48
+ @path.stat.size
49
+ end
50
+
51
+ def size
52
+ stat.size
53
+ end
44
54
  end
45
55
  end