{"id":13878681,"url":"https://github.com/blocknotes/prawn-html","last_synced_at":"2025-05-07T13:06:55.789Z","repository":{"id":38051591,"uuid":"394426582","full_name":"blocknotes/prawn-html","owner":"blocknotes","description":"HTML to PDF renderer using Prawn PDF","archived":false,"fork":false,"pushed_at":"2023-01-09T18:47:34.000Z","size":297,"stargazers_count":62,"open_issues_count":5,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-07T13:06:50.103Z","etag":null,"topics":["pdf","prawn-pdf","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/blocknotes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["blocknotes"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2021-08-09T20:16:18.000Z","updated_at":"2025-02-20T14:46:00.000Z","dependencies_parsed_at":"2023-02-08T13:31:16.987Z","dependency_job_id":null,"html_url":"https://github.com/blocknotes/prawn-html","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blocknotes%2Fprawn-html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blocknotes%2Fprawn-html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blocknotes%2Fprawn-html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blocknotes%2Fprawn-html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blocknotes","download_url":"https://codeload.github.com/blocknotes/prawn-html/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252883204,"owners_count":21819160,"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":["pdf","prawn-pdf","ruby"],"created_at":"2024-08-06T08:01:56.646Z","updated_at":"2025-05-07T13:06:55.766Z","avatar_url":"https://github.com/blocknotes.png","language":"Ruby","readme":"# Prawn HTML\n[![gem version](https://badge.fury.io/rb/prawn-html.svg)](https://rubygems.org/gems/prawn-html)\n[![gem downloads](https://badgen.net/rubygems/dt/prawn-html)](https://rubygems.org/gems/prawn-html)\n[![maintainability](https://api.codeclimate.com/v1/badges/db674db00817d56ca1e9/maintainability)](https://codeclimate.com/github/blocknotes/prawn-html/maintainability)\n[![linters](https://github.com/blocknotes/prawn-html/actions/workflows/linters.yml/badge.svg)](https://github.com/blocknotes/prawn-html/actions/workflows/linters.yml)\n[![specs](https://github.com/blocknotes/prawn-html/actions/workflows/specs.yml/badge.svg)](https://github.com/blocknotes/prawn-html/actions/workflows/specs.yml)\n\nHTML to PDF renderer using [Prawn PDF](https://github.com/prawnpdf/prawn).\n\nFeatures:\n- support a [good set](#supported-tags--attributes) of HTML tags and CSS properties;\n- handle [document styles](#document-styles);\n- custom [data attributes](#data-attributes) for Prawn PDF features;\n- no extra settings: it just parses an input HTML and outputs to a Prawn PDF document.\n\n**Notice**: render HTML documents properly is not an easy task, this gem support only some HTML tags and a small set of CSS attributes. If you need more rendering accuracy take a look at other projects like *WickedPDF* or *PDFKit*.\n\n\u003e [prawn-styled-text](https://github.com/blocknotes/prawn-styled-text) rewritten from scratch, finally!\n\nPlease :star: if you like it.\n\n## Install\n\n- Add to your Gemfile: `gem 'prawn-html'` (and execute `bundle`)\n- Just call `PrawnHtml.append_html` on a `Prawn::Document` instance (see the examples)\n\n## Examples\n\n```rb\nrequire 'prawn-html'\npdf = Prawn::Document.new(page_size: 'A4')\nPrawnHtml.append_html(pdf, '\u003ch1 style=\"text-align: center\"\u003eJust a test\u003c/h1\u003e')\npdf.render_file('test.pdf')\n```\n\nTo check some examples with the PDF output see [examples](examples/) folder.\n\nAlternative form using _PrawnHtml::Instance_ to preserve the context:\n\n```rb\nrequire 'prawn-html'\npdf = Prawn::Document.new(page_size: 'A4')\nphtml = PrawnHtml::Instance.new(pdf)\ncss = \u003c\u003c~CSS\n  h1 { color: green }\n  i { color: red }\nCSS\nphtml.append(css: css)\nphtml.append(html: '\u003ch1\u003eSome \u003ci\u003eHTML\u003c/i\u003e before\u003c/h1\u003e')\npdf.text 'Some Prawn text'\nphtml.append(html: '\u003ch1\u003eSome \u003ci\u003eHTML\u003c/i\u003e after\u003c/h1\u003e')\npdf.render_file('test.pdf')\n```\n\n## Supported tags \u0026 attributes\n\nHTML tags (using MDN definitions):\n\n- **a**: the Anchor element\n- **b**: the Bring Attention To element\n- **blockquote**: the Block Quotation element\n- **br**: the Line Break element\n- **code**: the Inline Code element\n- **del**: the Deleted Text element\n- **div**: the Content Division element\n- **em**: the Emphasis element\n- **h1** - **h6**: the HTML Section Heading elements\n- **hr**: the Thematic Break (Horizontal Rule) element\n- **i**: the Idiomatic Text element\n- **ins**: the added text element\n- **img**: the Image Embed element\n- **li**: the list item element\n- **mark**: the Mark Text element\n- **ol**: the Ordered List element\n- **p**: the Paragraph element\n- **pre**: the Preformatted Text element\n- **s**: the strike-through text element\n- **small**: the side comment element\n- **span**: the generic inline element\n- **strong**: the Strong Importance element\n- **sub**: the Subscript element\n- **sup**: the Superscript element\n- **u**: the Unarticulated Annotation (Underline) element\n- **ul**: the Unordered List element\n\nCSS attributes (dimensional units are ignored and considered in pixel):\n\n- **background**: for *mark* tag (3/6 hex digits or RGB or color name), ex. `style=\"background: #FECD08\"`\n- **break-after**: go to a new page after some elements, ex. `style=\"break-after: auto\"`\n- **break-before**: go to a new page before some elements, ex. `style=\"break-before: auto\"`\n- **color**: (3/6 hex digits or RGB or color name) ex. `style=\"color: #FB1\"`\n- **font-family**: font must be registered, quotes are optional, ex. `style=\"font-family: Courier\"`\n- **font-size**: ex. `style=\"font-size: 20px\"`\n- **font-style**: values: *:italic*, ex. `style=\"font-style: italic\"`\n- **font-weight**: values: *:bold*, ex. `style=\"font-weight: bold\"`\n- **height**: for *img* tag, ex. `\u003cimg src=\"image.jpg\" style=\"height: 200px\"/\u003e`\n- **href**: for *a* tag, ex. `\u003ca href=\"http://www.google.com/\"\u003eGoogle\u003c/a\u003e`\n- **left**: see *position (absolute)*\n- **letter-spacing**: ex. `style=\"letter-spacing: 1.5\"`\n- **line-height**: ex. `style=\"line-height: 10px\"`\n- **list-style-type**: for *ul*, a string, ex. `style=\"list-style-type: '- '\"`\n- **margin-bottom**: ex. `style=\"margin-bottom: 10px\"`\n- **margin-left**: ex. `style=\"margin-left: 15px\"`\n- **margin-top**: ex. `style=\"margin-top: 20px\"`\n- **position**: `absolute`, ex. `style=\"position: absolute; left: 20px; top: 100px\"`\n- **src**: for *img* tag, ex. `\u003cimg src=\"image.jpg\"/\u003e`\n- **text-align**: `left` | `center` | `right` | `justify`, ex. `style=\"text-align: center\"`\n- **text-decoration**: `underline`, ex. `style=\"text-decoration: underline\"`\n- **top**: see *position (absolute)*\n- **width**: for *img* tag, support also percentage, ex. `\u003cimg src=\"image.jpg\" style=\"width: 50%; height: 200px\"/\u003e`\n\nThe above attributes supports the `initial` value to reset them to their original value.\n\nFor colors, the supported formats are:\n- 3 hex digits, ex. `color: #FB1`;\n- 6 hex digits, ex. `color: #abcdef`;\n- RGB, ex. `color: RGB(64, 0, 128)`;\n- color name, ex. `color: yellow`.\n\n## Data attributes\n\nSome custom data attributes are used to pass options:\n\n- **dash**: for *hr* tag, accepts an integer or a list of integers), ex. `data-data=\"2, 4, 3\"`\n- **mode**: allow to specify the text mode (stroke|fill||fill_stroke), ex. `data-mode=\"stroke\"`\n\n## Document styles\n\nYou can define document CSS rules inside an _head_ tag. Example:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003ctitle\u003eA test\u003c/title\u003e\n  \u003cstyle\u003e\n    body { color: #abbccc }\n    .green {\n      color: #0f0;\n      font-family: Courier;\n    }\n    #test-1 { font-weight: bold }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"green\"\u003e\n    Div content\n    \u003cspan id=\"test-1\"\u003eSpan content\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Additional notes\n\n### Rails: generate PDF on the fly\n\nSample controller's action to create a PDF from Rails:\n\n```rb\nclass SomeController \u003c ApplicationController\n  def sample_action\n    respond_to do |format|\n      format.pdf do\n        pdf = Prawn::Document.new\n        PrawnHtml.append_html(pdf, '\u003ch1 style=\"text-align: center\"\u003eJust a test\u003c/h1\u003e')\n        send_data(pdf.render, filename: 'sample.pdf', type: 'application/pdf')\n      end\n    end\n  end\nend\n```\n\nMore details in this blogpost: [generate PDF from HTML](https://www.blocknot.es/2021-08-20-rails-generate-pdf-from-html/)\n\n## Do you like it? Star it!\n\nIf you use this component just star it. A developer is more motivated to improve a project when there is some interest.\n\nOr consider offering me a coffee, it's a small thing but it is greatly appreciated: [about me](https://www.blocknot.es/about-me).\n\n## Contributors\n\n- [Mattia Roccoberton](https://www.blocknot.es): author\n\n## License\n\nThe gem is available as open-source under the terms of the [MIT](LICENSE.txt).\n","funding_links":["https://github.com/sponsors/blocknotes"],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblocknotes%2Fprawn-html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblocknotes%2Fprawn-html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblocknotes%2Fprawn-html/lists"}