{"id":22695943,"url":"https://github.com/nvoynov/marko","last_synced_at":"2025-04-13T03:26:29.801Z","repository":{"id":65151864,"uuid":"583848401","full_name":"nvoynov/marko","owner":"nvoynov","description":"Markup Compiler for bulky sofware artifacts like SRS, ADD presented as bunch of separate files in sort of \"docs-as-code\" manner. It simple, but powerful applied together with Git and Pandoc","archived":false,"fork":false,"pushed_at":"2024-03-19T09:56:36.000Z","size":719,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T20:22:05.874Z","etag":null,"topics":["docs-as-code","markdown","ruby"],"latest_commit_sha":null,"homepage":"https://nvoynov.github.io/marko/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nvoynov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-31T06:30:05.000Z","updated_at":"2023-09-11T01:44:35.000Z","dependencies_parsed_at":"2023-11-06T11:38:31.007Z","dependency_job_id":"4a1dca53-02b9-402d-ad93-485647bc7ab4","html_url":"https://github.com/nvoynov/marko","commit_stats":{"total_commits":13,"total_committers":1,"mean_commits":13.0,"dds":0.0,"last_synced_commit":"91bff46ce95573a871ab37d35392bddda5f2d567"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvoynov%2Fmarko","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvoynov%2Fmarko/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvoynov%2Fmarko/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvoynov%2Fmarko/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvoynov","download_url":"https://codeload.github.com/nvoynov/marko/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248658763,"owners_count":21140997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docs-as-code","markdown","ruby"],"created_at":"2024-12-10T04:12:22.814Z","updated_at":"2025-04-13T03:26:29.769Z","avatar_url":"https://github.com/nvoynov.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: Marko Readme\nkeywords:\n- ruby\n- markup-compiler\n...\n\nMarko is a markup compiler that builds a tree from separated sources and compiles it into a single deliverable artifact.\n\nMarko supplies a \"docs-as-code\" approach for compiling bulky software artifacts by providing source storage, original plain text markup, compiler templates, Ruby- and a command-line interface for assembling and compiling.\n\nHaving assembled the artifact, it can be analyzed, enriched by extra data, etc.; it can serve as a source for deriving subdued artifacts.  \n\nI've applied the approach for dozens of artifacts for the last six years, mainly writing requirements in Markdown, analyzing quality, deriving estimation sheets, exporting deliverables with Pandoc, and automating some parts of my everyday work.\n\n## Installation\n\nInstall the gem by executing:\n\n    $ gem install marko\n\n## Usage\n\n### Interface\n\nMarko provides just basic command-line interface for creating new projects and assembling artifacts - run `$ marko` to see the details.\n\nIn addition to the standard CLI, Marko supplies you with Rakefile, that also serves as custom automation example. You can run `rake -T` to see available commands.\n\nTo help you with task automation, Marko provides `Marko.assemble` for assembling and `Marko.compile` for compiling artifacts (you could already spot it inside Rakefile.) See [Automation](#automation) section for examples.\n\n### Structure\n\n`marko new PROJECT` command will create a new Marko project inside the `PROJECT` directory with following structure:\n\n- [bin/](bin/) - output folder for `build`\n- [bin/assets/](bin/assets/) - assets folder\n- [src/](src/) - markup sources\n- [tt/](tt/) - compiler templates\n- [marko.yml](marko.yml) - project configuration\n- [Rakefile](Rakefile) - Rake automation file\n- [README.md](README.md) - this file\n\n### Markup\n\nThe basic and the only Marko entity is [TreeNode](#github-link) with `id`, `meta`, `body`, and `items` properties.\n\nAnd the primary activity is just writing source files consisting of the TreeNode, where the source actually just a regular Markdown with an optional metadata excerpt. All lines from `#` until the next `#` are considered TreeNode.\n\nLet's see it by example and assume one has a few separate sources `content.md`, `uc.signup.md`, and `uc.signin.md`.\n`content.md`\n\n```markdown\n# Overview\n# User Requirements\n## Use Cases\n{{id: uc, order_index: .signup .signin}}\n# Functional requirements\n```\n\n`uc.signup.md`\n\n```markdown\n# Sign-Up\n{{id: .signup, parent: uc}}\n\nbody markup\n```\n\n`uc.signin.md`\n\n```markdown\n# Sign-In\n{{id: .signin, parent: uc}}\n\nbody markup\n```\n\nThese sources will be assembled in a single hierarchy as follows\n\n```markdown\n# Overview\n# User Requirements\n## Use Cases\n{{id: uc, order_index: .signup .signin}}\n### Sign-Up\n{{id: .signup, parent: uc}}\n\nbody markup\n### Sign-In\n{{id: .signin, parent: uc}}\n\nbody markup\n\n# Functional requirements\n```\n\nSo all the assemblage magic is just linking TreeNode by using `id`, `parent`, and `order_index` attributes; where `id` and `parent` are just nodes identifiers, and `order_index` is just an array of identifiers that point out the order of getting `items`.\n\n### Metadata\n\nIt was shown above how to provide hierarchy attributes by metadata excerpt `{{}}`. But you can also use the excerpt to provide your own attributes, like `source: John Doe`, `affects: some.other.thing`, etc.\n\n### Tree, IDs\n\nWhen you deal with trees in separated sources, to reference nodes you need identifiers. So when you write `id`, `parent` and `order_index` metadata - you actually deal with TreeNode Id, and it must be unique.  \n\nWhen one works on a simple parent -\u003e child relationship, identifiers can be shortened by starting from `.`. In the example above `{{order_index: .signup .signin}}`, the parent will find its children by `/.signup$/` and `/.signin$/`; and besides, during the assembling phase those relative identifiers will be turned to full - `uc.signup` and `uc.signin`.\n\nMarko will generate a unique Id for each TreeNode when Id was not provided by the author.\n\n### Macros\n\nThe TreeNode.body can include macros. The most helpful one is `[[reference.id]]` that will be substituted by well-formed markdown link `[\u003cnode.title\u003e](#\u003cnode.url\u003e)`. There are also `@@tree`, `@@list`, `@@todo`, and `@@skip` standard macros; and this list could be extended or shortened through building templates.  \n\n- `@@tree` substituted by the tree of references to all descendants of the current node, might be used for the table of contents;\n- `@@list` substituted by the list of references to node items;\n- `@@todo` will skip text with the macro till the end of the line\n- `@@skip` will skip the text after the macro\n\n### Templates\n\nMarko uses templates placed under the `tt` folder to compile sources into artifacts. You can use and customize the default one or design your own for particular purposes. It's just pure ERB, where Marko renders collection of decorated TreeNodes.\n\n```\n% @model.each do |node|\n\u003c%= node.text %\u003e\n% end\n```\n\nThe `marko.yml` configuration file sets the building process's default template and other default values.\n\n```yml\ntitle: Artifact\ntemplate: tt/default.md.tt\nfilename: bin/artifact.md\n```\n\n### Automation\n\nFollowing quick example will assemble tree, remove TreeNode with id == 'hint', and compile the tree. You can also see Rakefile for other examples.\n\n```ruby\nrequire 'marko'\n\ndef do_remove_hint\n  tree = Marko.assemble\n  hint = tree.find_node('hint')\n  hint.orphan!\n  Marko.compile(tree: tree)  \nend\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/marko.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvoynov%2Fmarko","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvoynov%2Fmarko","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvoynov%2Fmarko/lists"}