README.md in grokdown-0.3.0 vs README.md in grokdown-0.4.0
- old
+ new
@@ -1,25 +1,120 @@
-# Grokdown
+# Grokdown: Markdown to Ruby Objects
-Grok Markdown documents with Ruby objects. Have fun using whats inside Markdown documents, without all of the pain of walking a document tree.
+`Grokdown` provides **an experimental interface** for building value objects and composing them into entities from a Markdown document tree.
-## Grok
+## Usage
-> - to understand intuitively or by empathy, to establish rapport with
-> - to empathize or communicate sympathetically (with); also, to experience
-> enjoyment
+Include the `Grokdown` module into ruby classes you want `Grokdown::Document` to consider building value objects from.
-## Markdown
+`Grokdown::Document` depends on class methods `matches_node?` and `agruments_from_node` to select which `Grokdown` class to build and how to build an instance from a Markdown node.
-> Markdown allows you to write using an easy-to-read, easy-to-write plain text
-> format, then convert it to structurally valid XHTML (or HTML).
+`Grokdown` instances can compose `Grokdown` value objects or entities by implementing instance hook methods following a naming convention. The hook method name is `add_` prefixing the snake case `Grokdown` class name of the instances a `Grokdown` instance can get added.
+Implementing the hook methods creates precise and resilient factories for objects from Markdown documents.
+
+Receiver | Hook method | Use case
+--- | --- | ---
+Class | `matches_node?` | Predicate to select receiving class to build from a given Markdown node|
+Class | `arguments_from_node` | Maps node values to build an instance of the class from a given Markdown node |
+Instance | `add_other_class_name` | Aggregate later `OtherClassName` instances when visiting the Markdown node tree |
+
+Simple differences in implementations of `add_` composition methods enables building useful ruby object graphs from easy to write Markdown files.
+
+### Extracting License information from README.md
+
+Create a `.grokdown` file which defines types to build from markdown nodes, then use the `grokdown` CLI to extract the license name with:
+
+```sh
+grokdown -e "Document.new(File.read('README.md')).first.license.name"
+```
+
+##### `README.md`
+
+```
+# Example Readme
+
+Simple readme with a conventional `## License` section
+
+## License
+
+The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
+```
+
+##### `.grokdown`
+
+```ruby
+require "grokdown"
+
+class Text < String
+ include Grokdown
+
+ def self.matches_node?(node) = node.type == :text
+
+ def self.arguments_from_node(node) = node.string_content
+end
+
+Link = Struct.new(:href, :title, :text, :parent, keyword_init: true) do
+ include Grokdown
+
+ def self.matches_node?(node) = node.type == :link
+
+ def self.arguments_from_node(node) = {href: node.url, title: node.title}
+
+ def add_text(node)
+ return if text
+
+ self.text = node
+
+ parent.add_composable(node) if parent&.can_compose?(node)
+ end
+end
+
+License = Struct.new(:text, :href, :name, :link, keyword_init: true) do
+ include Grokdown
+
+ def self.matches_node?(node) = node.type == :header && node.header_level == 2 && node.first_child.string_content == "License"
+
+ def add_text(node) = self.text = node
+
+ extend Forwardable
+
+ def_delegator :link, :href
+
+ def add_link(node)
+ node.parent = self
+ self.link = node
+ end
+
+ def add_text(node) = self.name = node
+end
+
+Struct.new(:text, :link, :keyword_init) do
+ include Grokdown
+
+ def self.matches_node?(node) = node.type == :header && node.header_level == 2
+
+ def add_text(node) = self.text = node
+ def add_link(node) = self.link = node
+end
+
+Readme = Struct.new(:license) do
+ include Grokdown
+
+ def self.matches_node?(node) = node.type == :document
+
+ def add_license(node) = self.license = node
+end
+```
+
## Installation
Install the gem and add to the application's Gemfile by executing:
+
$ bundle add grokdown
If bundler is not being used to manage dependencies, install the gem by executing:
+
$ gem install grokdown
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.