{"id":31794537,"url":"https://github.com/andypearson/trundle","last_synced_at":"2026-04-20T14:02:13.168Z","repository":{"id":28354982,"uuid":"31868755","full_name":"andypearson/trundle","owner":"andypearson","description":"A gem for reading and writing TextBundle files.","archived":false,"fork":false,"pushed_at":"2015-08-20T21:50:15.000Z","size":240,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-19T04:19:04.629Z","etag":null,"topics":["gem","markdown","ruby","textbundle"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andypearson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-08T22:41:23.000Z","updated_at":"2018-11-16T11:20:41.000Z","dependencies_parsed_at":"2022-08-25T10:10:47.733Z","dependency_job_id":null,"html_url":"https://github.com/andypearson/trundle","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/andypearson/trundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andypearson%2Ftrundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andypearson%2Ftrundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andypearson%2Ftrundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andypearson%2Ftrundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andypearson","download_url":"https://codeload.github.com/andypearson/trundle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andypearson%2Ftrundle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32050451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["gem","markdown","ruby","textbundle"],"created_at":"2025-10-10T19:46:19.830Z","updated_at":"2026-04-20T14:02:13.119Z","avatar_url":"https://github.com/andypearson.png","language":"Ruby","readme":"# trundle\n\nA gem for reading and writing [TextBundle](http://textbundle.org/) files.\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'trundle'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install trundle\n\n\n## Usage\n\n### Reading an existing TextBundle\n\nImagine you've got a TextBundle file saved at `~/example-bundle.textbundle`\n\nYou can open that very easily with just:\n\n```ruby\nexample = Trundle.open('~/example-bundle.textbundle')\n```\n\nThat'll give you an instance of a `Trundle::TextBundle` and you'll be able to read out the text content of the bundle using:\n\n```ruby\nexample.text\n```\n\nYou can also access all of the core attributes outlined in the specification:\n\n```ruby\nexample.creator_identifier\nexample.creator_url\nexample.source_url\nexample.type\nexample.version\n```\n\nAs well as finding out if this TextBundle is transient or not:\n\n```ruby\nexample.transient?\n```\n\n### Writing a TextBundle\n\nNow imagine you'd like to create a new TextBundle, you can do that by opening a file where one does not already exist (just as you usually do in Ruby)\n\n```ruby\nmy_example = Trundle.open('~/my-example-bundle.textbundle')\n```\n\nSetting the text content of this bundle is as easy as:\n\n```ruby\nmy_example.text = 'This is my bundle!'\n```\n\nAnd you can set the values in a similar way:\n\n```ruby\nexample.creator_identifier = 'com.my-app'\nexample.creator_url = 'http://my-app.com'\nexample.source_url = 'http://my-app.com'\nexample.type = 'net.daringfireball.markdown'\nexample.version = 2\nexample.transient = false\n```\n\nOnce you're happy with the state of your new TextBundle you can save it to the filesystem by calling:\n\n```ruby\nexample.close\n```\n\nPassing a block to `Trundle.open` will set values and write the bundle in one fell swoop:\n\n```ruby\nTrundle.open('~/my-example-bundle.textbundle') do |tb|\n  tb.text = 'This is my bundle!'\n  tb.source_url = 'http://my-app.com'\nend\n```\n\n\n### Setting up default values\n\nSetting up your new TextBundles over and over again can get pretty boring. Instead, you can set up defaults that'll apply to any TextBundle that you create:\n\n```ruby\nTrundle.configure do |config|\n  config.creator_identifier = 'com.my-app'\n  config.creator_url = 'http://my-app.com'\n  config.source_url = 'http://my-app.com'\n  config.type = 'net.daringfireball.markdown'\n  config.version = 2\n  config.transient = false\nend\n```\n\nOut of the box, trundle is setup with the following defaults:\n\n```ruby\nTrundle.configure do |config|\n  config.version = 2\n  config.transient = false\nend\n```\n\n\n### Working with namespaces\n\nApplications can add custom meta data to any TextBundle by including it under a unique application key. In Trundle, this is called a namespace.\n\nYou need to tell trundle about the namespaces that you'd like to work with. You can do that in the config:\n\n```ruby\nTrundle.configure do |config|\n  config.namespaces do\n    my_app 'com.my-app'\n  end\nend\n```\n\nThe bit on the left defines the name of the accessor method and the bit on the right is the application key that'll be read and written. You can setup as many namespaces as you need.\n\nOnce trundle knows about your namespaces, you can read custom values from them:\n\n```ruby\nexisting_document = Trundle.open('~/document.textbundle')\nexisting_document.my_app.version\nexisting_document.my_app.document_type\n```\n\nAnd also write custom values too:\n\n```ruby\nmy_document = Trundle.open('~/my-document.textbundle')\nmy_document.my_app.version = 42\nmy_document.my_app.document_type = 'Article'\nmy_document.close\n```\n\n\n## Next things\n\n- TODO: rubocop the code\n- TODO: add support for assets\n- TODO: could the configuration DSL be more succinct?\n- TODO: default values for namespaces?\n\n## Contributing\n\n1. Fork it ( https://github.com/andypearson/trundle/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandypearson%2Ftrundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandypearson%2Ftrundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandypearson%2Ftrundle/lists"}