gloo-md 1.2 → 1.4

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 (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -0
  3. data/lib/md.rb +36 -5
  4. data/lib/md_doc.rb +75 -6
  5. metadata +6 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26d3d6ba34f0daaa4881b63fa84848e8ad01043d34357e67d93aad97d85bfe64
4
- data.tar.gz: cd27b868d2846861b17031cbf2076c24b1f1d996238f208d5e2a1760533086d3
3
+ metadata.gz: 0fabc46f939b1be7b157b2ac465d414d49229dcdfa9a488d975027e72a1b0c77
4
+ data.tar.gz: eaee04c792674ccdc41fa779940ba8da31e4943f885238521591ccfef1d33775
5
5
  SHA512:
6
- metadata.gz: 670f1cc4ca37f23fcd67ae241c26bb8c334d9cef5a49de5b5d4b3ac587e629d5f02a3999fdf390c1642c94aeec829b63ccbc4bb6da49a338fb317d81ff0ca2ba
7
- data.tar.gz: cc147be4c2af1f0a82e64e504e397d6f76f32cc11e34c38d85645e6ef69324339d67b34f416e5d1a3c948cf9abfa5c37fe48236745031712a487c4c29d77aefd
6
+ metadata.gz: 4aebf3742809ae3b86e3e17ffbfc308b847083a76a1cda6bac82e2378b01853ac87f4bfec7390b95565e48d95794fad769d6194c08399ec6c52afbdc66d41df0
7
+ data.tar.gz: 36b30547c2ab17834f42e34b1376248244d2cd1a6bcbc984290f01ee499dea04beac810ac8891f34631a0dba5360546e775703c78070e99d27bd4c36fb587345
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # gloo-md
2
+
3
+ A core gloo library for markdown rendering.
4
+
5
+ ## Usage
6
+
7
+ Load this library in a gloo script:
8
+
9
+ ```gloo
10
+ > load lib md
11
+ ```
12
+
13
+ ## Objects
14
+
15
+ - `markdown` — markdown data in a text string, with rendering support
16
+ - `md_doc` — a markdown file with YAML frontmatter
17
+
18
+ ## Full Reference
19
+
20
+ Every object's children and messages are documented in-app once the library is loaded — e.g. `help> object markdown`.
data/lib/md.rb CHANGED
@@ -117,14 +117,45 @@ class Md < Gloo::Core::Obj
117
117
  # Redcarpet markdown processor.
118
118
  #
119
119
  def self.md_2_html( md )
120
- markdown = Redcarpet::Markdown.new(
121
- Redcarpet::Render::HTML,
122
- autolink: true,
120
+ markdown = Redcarpet::Markdown.new(
121
+ Redcarpet::Render::HTML,
122
+ autolink: true,
123
123
  fenced_code_blocks: true,
124
- tables: true,
124
+ tables: true,
125
125
  strikethrough: true )
126
-
126
+
127
127
  return markdown.render( md )
128
128
  end
129
129
 
130
+ # ---------------------------------------------------------------------
131
+ # Object Documentation
132
+ # ---------------------------------------------------------------------
133
+
134
+ #
135
+ # Get the object's documentation data.
136
+ #
137
+ def self.doc_data
138
+ {
139
+ :name => KEYWORD,
140
+ :shortcut => KEYWORD_SHORT,
141
+ :description => 'Markdown data in a text string. Also supports ' \
142
+ 'gloo Markdown extensions (panel, note, quote, idea and check ' \
143
+ 'blocks) rendered via MarkdownExt when the data is rendered.',
144
+ :messages => [
145
+ 'show — Show the markdown data in the terminal.',
146
+ 'render ({dst}) — Convert the markdown to HTML and put it in the {dst} object. The HTML is also put into it either way.',
147
+ 'update_asset_path — Update asset paths for all images in the source markdown, so files can refer to images from a path different from the page using them.'
148
+ ],
149
+ :examples => <<~EXAMPLES.strip
150
+ md [can] :
151
+ f [file] :
152
+ on_load [script] :
153
+ put $.gloo.projects + "/o/data/txt.md" into md.f
154
+ tell md.f to read (md.data)
155
+ tell md.data to show
156
+ data [md] :
157
+ EXAMPLES
158
+ }
159
+ end
160
+
130
161
  end
data/lib/md_doc.rb CHANGED
@@ -79,7 +79,9 @@ class MdDoc < Gloo::Core::Obj
79
79
 
80
80
  #
81
81
  # Read the file at path, parse frontmatter and body, populate children.
82
- # Frontmatter children are created dynamically from whatever keys are present.
82
+ # Only scalar frontmatter values become gloo string children; complex values
83
+ # (arrays, nested hashes) are skipped — they are preserved on write by
84
+ # re-reading the file.
83
85
  #
84
86
  def msg_read
85
87
  path = resolve_path
@@ -96,6 +98,7 @@ class MdDoc < Gloo::Core::Obj
96
98
  fm_can = find_child FRONTMATTER
97
99
  if fm_can && fm_hash
98
100
  fm_hash.each do |key, val|
101
+ next unless scalar?( val )
99
102
  child = fm_can.find_add_child( key.to_s, 'string' )
100
103
  child.set_value val.to_s
101
104
  end
@@ -107,25 +110,35 @@ class MdDoc < Gloo::Core::Obj
107
110
 
108
111
  #
109
112
  # Serialize frontmatter and body children back to the file at path.
110
- # Creates the file if it does not exist.
113
+ # Re-reads the current file to get the base hash (preserving arrays and other
114
+ # complex values), then overlays the scalar children which may have been
115
+ # modified. Creates the file if it does not exist.
111
116
  #
112
117
  def msg_write
113
118
  path = resolve_path
114
119
  return unless path
115
120
 
121
+ expanded = File.expand_path( path )
122
+
123
+ # Re-read the file so arrays and nested hashes survive unchanged.
124
+ base = {}
125
+ if File.exist?( expanded )
126
+ base, _ = parse_frontmatter( File.read( expanded ) )
127
+ end
128
+
116
129
  fm_can = find_child FRONTMATTER
117
- fm_hash = {}
130
+
131
+ # Overlay scalar children; updating an existing key preserves its position.
118
132
  if fm_can
119
133
  fm_can.children.each do |child|
120
- fm_hash[ child.name ] = child.value
134
+ base[ child.name ] = child.value
121
135
  end
122
136
  end
123
137
 
124
138
  body = find_child BODY
125
139
  body_text = body ? body.value.to_s : ''
126
140
 
127
- content = build_content( fm_hash, body_text )
128
- File.write( File.expand_path( path ), content )
141
+ File.write( expanded, build_content( base, body_text ) )
129
142
  end
130
143
 
131
144
 
@@ -135,6 +148,15 @@ class MdDoc < Gloo::Core::Obj
135
148
 
136
149
  private
137
150
 
151
+ #
152
+ # True for scalar YAML values that can be stored as gloo string children.
153
+ # Arrays, hashes, and other complex types are skipped on read.
154
+ #
155
+ def scalar?( val )
156
+ val.is_a?( String ) || val.is_a?( Integer ) || val.is_a?( Float ) ||
157
+ val.is_a?( TrueClass ) || val.is_a?( FalseClass ) || val.nil?
158
+ end
159
+
138
160
  #
139
161
  # Get the expanded path string from the path child.
140
162
  #
@@ -175,4 +197,51 @@ class MdDoc < Gloo::Core::Obj
175
197
  "---\n#{fm_yaml}---\n#{body_text}"
176
198
  end
177
199
 
200
+ # ---------------------------------------------------------------------
201
+ # Object Documentation
202
+ # ---------------------------------------------------------------------
203
+
204
+ #
205
+ # Get the object's documentation data.
206
+ #
207
+ def self.doc_data
208
+ {
209
+ :name => KEYWORD,
210
+ :shortcut => KEYWORD_SHORT,
211
+ :description => 'A Markdown file with YAML frontmatter. Holds a ' \
212
+ 'path to a .md file and exposes the frontmatter fields as ' \
213
+ 'dynamic string children under frontmatter, and the Markdown ' \
214
+ 'body as a text child under body. Use read to load a file into ' \
215
+ 'the object tree and write to serialize it back. Both ' \
216
+ 'frontmatter and body can be modified between a read and a write.',
217
+ :children => [
218
+ 'path (file) — Path to the Markdown file.',
219
+ 'frontmatter (container) — Container whose children map to YAML frontmatter keys.',
220
+ 'body (text) — The Markdown body (everything after the --- closing delimiter).'
221
+ ],
222
+ :messages => [
223
+ 'read — Read the file at path, parse the YAML frontmatter and Markdown body. Frontmatter children are created dynamically from whatever keys are present in the file. Populates frontmatter.* children and body.',
224
+ 'write — Serialize frontmatter children back to YAML and combine with body. Writes the result to the file at path, creating it if it does not exist. Key order is preserved; quoting style may normalize on first write, but semantic content is unchanged.'
225
+ ],
226
+ :notes => 'If the file has no frontmatter block, frontmatter ' \
227
+ 'will have no children and body will contain the full file ' \
228
+ 'content. If path is empty or the file does not exist, read ' \
229
+ 'logs an error and returns without modifying children. Uses ' \
230
+ "Ruby's built-in psych library for YAML parsing — no " \
231
+ 'additional dependencies.',
232
+ :examples => <<~EXAMPLES.strip
233
+ doc [md_doc] :
234
+ path [file] : ~/notes/project.md
235
+ frontmatter [can] :
236
+ body [text] :
237
+
238
+ on_load [script] :
239
+ load lib md
240
+ tell doc to read
241
+ show doc.frontmatter.title
242
+ show doc.body
243
+ EXAMPLES
244
+ }
245
+ end
246
+
178
247
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gloo-md
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: '1.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Crane
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-06-26 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: redcarpet
@@ -31,16 +30,17 @@ executables: []
31
30
  extensions: []
32
31
  extra_rdoc_files: []
33
32
  files:
33
+ - README.md
34
34
  - lib/gloo-md.rb
35
35
  - lib/markdown_ext.rb
36
36
  - lib/md.rb
37
37
  - lib/md_doc.rb
38
- homepage: https://gloo.ecrane.us/
38
+ homepage: https://github.com/ecrane/gloo
39
39
  licenses:
40
40
  - MIT
41
41
  metadata:
42
42
  gloo.type: core-library
43
- post_install_message:
43
+ documentation_uri: https://github.com/ecrane/gloo
44
44
  rdoc_options: []
45
45
  require_paths:
46
46
  - lib
@@ -55,8 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
57
  requirements: []
58
- rubygems_version: 3.5.16
59
- signing_key:
58
+ rubygems_version: 4.0.17
60
59
  specification_version: 4
61
60
  summary: Gloo core library. Markdown support.
62
61
  test_files: []