{"id":16225612,"url":"https://github.com/evanleck/berns","last_synced_at":"2025-03-19T12:31:03.972Z","repository":{"id":56842858,"uuid":"117730202","full_name":"evanleck/berns","owner":"evanleck","description":"A Ruby utility library for generating HTML strings","archived":false,"fork":false,"pushed_at":"2023-10-05T18:38:22.000Z","size":226,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-11T09:48:33.029Z","etag":null,"topics":["html","ruby"],"latest_commit_sha":null,"homepage":"","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/evanleck.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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":"2018-01-16T19:21:42.000Z","updated_at":"2023-07-22T01:38:54.000Z","dependencies_parsed_at":"2024-10-27T20:34:06.282Z","dependency_job_id":"ab5e4f1a-1c3e-44b3-8e0d-7ad6d7779011","html_url":"https://github.com/evanleck/berns","commit_stats":{"total_commits":111,"total_committers":2,"mean_commits":55.5,"dds":0.036036036036036,"last_synced_commit":"7ebbefcf1fde06fb2cb7520422e23024f98f525c"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanleck%2Fberns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanleck%2Fberns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanleck%2Fberns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanleck%2Fberns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evanleck","download_url":"https://codeload.github.com/evanleck/berns/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244426577,"owners_count":20450990,"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":["html","ruby"],"created_at":"2024-10-10T12:45:40.217Z","updated_at":"2025-03-19T12:31:03.967Z","avatar_url":"https://github.com/evanleck.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Berns\n\n[![](https://badge.fury.io/rb/berns.svg)](https://badge.fury.io/rb/berns)\n[![](https://github.com/evanleck/berns/actions/workflows/main.yml/badge.svg)](https://github.com/evanleck/berns/actions/workflows/main.yml)\n\nA utility library for generating HTML strings.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n``` ruby\ngem 'berns'\n```\n\nAnd then execute:\n\n``` sh\nbundle\n```\n\nOr install it yourself as:\n\n``` sh\ngem install berns\n```\n\n*Note:* Berns is only tested on Ruby's MRI/CRuby interpreter version 2.7 and\ngreater. Berns version 3.x and below support Ruby 2.5. Contributions are welcome\nto get JRuby or TruffleRuby working.\n\n## Usage\n\nNote that all return string values will be UTF-8 encoded.\n\n### `void(tag, attributes)`\n\nThe `void` method generates a void HTML element i.e. one without any content. It\ntakes either a symbol or a string and an optional hash of HTML attributes.\n\n``` ruby\nBerns.void('br') # =\u003e '\u003cbr\u003e'\nBerns.void('br', class: 'br-class') # =\u003e '\u003cbr class=\"br-class\"\u003e'\n```\n\n### `element(tag, attributes) { content }`\n\nThe `element` method generates a standard HTML element i.e. one with optional\ncontent. It takes either a symbol or a string, an optional hash of HTML\nattributes, and an optional block of content. If provided, the block should\nreturn a string.\n\n``` ruby\nBerns.element('div') # =\u003e '\u003cdiv\u003e\u003c/div\u003e'\nBerns.element('div', class: 'div-class') # =\u003e '\u003cdiv class=\"div-class\"\u003e\u003c/div\u003e'\nBerns.element('div', class: 'div-class') { 'Content' } # =\u003e '\u003cdiv class=\"div-class\"\u003eContent\u003c/div\u003e'\n```\n\n### `to_attribute(attribute, value)`\n\nThe `to_attribute` method generates an HTML attribute string. If the value is a\nhash then the attribute is treated as a prefix.\n\n``` ruby\nBerns.to_attribute('class', 'my-class another-class') # =\u003e 'class=\"my-class another-class\"'\nBerns.to_attribute('data', { foo: 'bar' }) # =\u003e 'data-foo=\"bar\"'\n```\n\nAll attribute values are HTML-escaped using [k0kubun/hescape](hescape) written\nby Takashi Kokubun.\n\n### `to_attributes(attributes)`\n\nThe `to_attributes` method generates an HTML attribute string from a hash by\ncalling `to_attribute` for each key/value pair.\n\n``` ruby\nBerns.to_attributes({ 'data' =\u003e { foo: 'bar' }, 'class' =\u003e 'my-class another-class' }) # =\u003e 'data-foo=\"bar\" class=\"my-class another-class\"'\n```\n\n### `escape_html(string)`\n\nThe `escape_html` method escapes HTML entities in strings using\n[k0kubun/hescape](hescape) written by Takashi Kokubun. As noted in the hescape\nrepository, it should be the same as `CGI.escapeHTML`.\n\n``` ruby\nBerns.escape_html('\u003c\"tag\"') # =\u003e '\u0026lt;\u0026quot;tag\u0026quot;'\n```\n\n### `sanitize(string)`\n\nThe `sanitize` method strips HTML tags from strings.\n\n``` ruby\nBerns.sanitize('This \u003cspan\u003eshould be clean\u003c/span\u003e') # =\u003e 'This should be clean'\n```\n\nNote that this is an extremely naive implementation of HTML sanitization that\nliterally just looks for \"\u003c\" and \"\u003e\" characters and removes the contents between\nthem. This should probably only be used on trusted strings.\n\n### `build { content }`\n\nThe `build` method uses `Berns::Builder` to let you create HTML strings using a\nDSL.\n\n``` ruby\nBerns.build { h1 { 'Heading' } } # =\u003e '\u003ch1\u003eHeading\u003c/h1\u003e'\n```\n\nSee below for more on `Berns::Builder`.\n\n### `Berns::Builder` HTML DSL\n\nAdded in version 3.4.0 and heavily inspired by the likes of\n[Papercraft](papercraft), [Markaby](markaby), and [Arbre](arbre), the\n`Berns::Builder` class lets you create HTML strings using a DSL.\n\n``` ruby\ntemplate = Berns::Builder.new do\n  h1 { 'Heading' }\n  p(class: 'paragraph') do\n    text 'Bare text here.'\n\n    b { 'Bold text here' }\n  end\nend\n```\n\nWithin the block provided to `Berns::Builder.new` every standard element method,\nvoid element method, `#element`, and `#void` are available as methods and each\ntime you use one of those methods the result is appended to an internal buffer.\nIn addition, the `#text` method appends HTML escaped text to the buffer and\n`#raw` appends text to the buffer without modification.\n\nThe block provided to `Berns::Builder.new` can take both positional and keyword\narguments.\n\n``` ruby\ntemplate = Berns::Builder.new do |content, title:|\n  h1 { title }\n  p(class: 'paragraph') { content }\nend\n\ntemplate.call('Some text.', title: 'The title') # =\u003e\n# \u003ch1\u003e\n#   The title\n# \u003c/h1\u003e\n# \u003cp\u003e\n#   Some text.\n# \u003c/p\u003e\n```\n\nOnce initialized, the `#call` method will render the template to a string. Any\narguments, positional or keyword, are passed through as-is to the block provided\nto `#new`.\n\n``` ruby\nstring = template.call # =\u003e\n# \u003ch1\u003e\n#   Heading\n# \u003c/h1\u003e\n# \u003cp class='paragraph'\u003e\n#   Bare text here.\n#   \u003cb\u003e\n#     Bold text here.\n#   \u003c/b\u003e\n# \u003c/p\u003e\n```\n\nIn addition to initializing a new instance of `Berns::Builder`, you can\nconstruct and render a template to a string all at once with `Berns.build`.\n\n``` ruby\nBerns.build do\n  h1 { 'Heading' }\n  p(class: 'paragraph') do\n    text 'Bare text here.'\n\n    b { 'Bold text here' }\n  end\nend # =\u003e\n# \u003ch1\u003e\n#   Heading\n# \u003c/h1\u003e\n# \u003cp class='paragraph'\u003e\n#   Bare text here.\n#   \u003cb\u003e\n#     Bold text here.\n#   \u003c/b\u003e\n# \u003c/p\u003e\n```\n\n### Standard and void elements\n\nAll standard and void HTML elements are defined as methods on Berns, so you can\ncreate e.g. a link with `Berns.a`. Below is the full list of standard elements\nwhich are also available in the constant `Berns::STANDARD` as an array of\nsymbols.\n\n```\na abbr address article aside audio b bdi bdo blockquote body button canvas\ncaption cite code colgroup datalist dd del details dfn dialog div dl dt em\nfieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header html i\niframe ins kbd label legend li main map mark menu meter nav noscript object ol\noptgroup option output p picture pre progress q rp rt ruby s samp script section\nselect small span strong style sub summary table tbody td template textarea\ntfoot th thead time title tr u ul var video\n```\n\nBelow is the full list of void elements that are defined as singleton methods on\nBerns which are also available in the constant `Berns::VOID` as an array of\nsymbols.\n\n```\narea base br col embed hr img input link menuitem meta param source track wbr\n```\n\n## Performance\n\nBerns 3 was a total rewrite from a pure Ruby implementation to one powered by a\nC extension. That rewrite is about three times faster than the pure Ruby\nimplementation used in version 2. See the file\n[benchmarks/performance.rb](benchmarks/performance.rb) for the benchmark code.\n\n``` example\nWarming up --------------------------------------\n                ruby    27.521k i/100ms\n               c-ext    74.915k i/100ms\nCalculating -------------------------------------\n                ruby    275.913k (± 1.0%) i/s -      1.404M in   5.087516s\n               c-ext    813.113k (± 1.0%) i/s -      4.120M in   5.067902s\n\nComparison:\n               c-ext:   813113.3 i/s\n                ruby:   275913.5 i/s - 2.95x  (± 0.00) slower\n```\n\n## Trivia\n\nThe name \"Berns\" is taken from the name of [the inventor of HTML](html), [Sir\nTim Berners-Lee](tim).\n\n\u003c!-- Links --\u003e\n[arbre]: https://github.com/activeadmin/arbre\n[hescape]: https://github.com/k0kubun/hescape\n[html]: https://en.wikipedia.org/wiki/HTML#Development\n[markaby]: https://github.com/markaby/markaby\n[papercraft]: https://github.com/digital-fabric/papercraft\n[tim]: https://en.wikipedia.org/wiki/Tim_Berners-Lee\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanleck%2Fberns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevanleck%2Fberns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanleck%2Fberns/lists"}