{"id":24576206,"url":"https://github.com/avo-hq/marksmith","last_synced_at":"2025-05-15T00:08:19.676Z","repository":{"id":273742623,"uuid":"918962139","full_name":"avo-hq/marksmith","owner":"avo-hq","description":"GitHub-style markdown editor for Ruby and Rails","archived":false,"fork":false,"pushed_at":"2025-04-29T06:51:08.000Z","size":1485,"stargazers_count":467,"open_issues_count":10,"forks_count":15,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-07T19:50:20.359Z","etag":null,"topics":["editor","markdown","markdown-editor","rails","ruby","ruby-on-rails","wysiwyg-editor"],"latest_commit_sha":null,"homepage":"https://avohq.io","language":"JavaScript","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/avo-hq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","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,"zenodo":null}},"created_at":"2025-01-19T10:54:05.000Z","updated_at":"2025-05-07T16:36:57.000Z","dependencies_parsed_at":"2025-04-15T00:46:20.727Z","dependency_job_id":"48641a78-6c65-4086-8f3c-c32396158555","html_url":"https://github.com/avo-hq/marksmith","commit_stats":null,"previous_names":["avo-hq/marksmith"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avo-hq%2Fmarksmith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avo-hq%2Fmarksmith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avo-hq%2Fmarksmith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avo-hq%2Fmarksmith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avo-hq","download_url":"https://codeload.github.com/avo-hq/marksmith/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254249202,"owners_count":22039029,"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":["editor","markdown","markdown-editor","rails","ruby","ruby-on-rails","wysiwyg-editor"],"created_at":"2025-01-23T22:22:11.348Z","updated_at":"2025-05-15T00:08:14.664Z","avatar_url":"https://github.com/avo-hq.png","language":"JavaScript","readme":"# Marksmith\n\n[![CI](https://github.com/avo-hq/marksmith/actions/workflows/ci.yml/badge.svg)](https://github.com/avo-hq/marksmith/actions/workflows/ci.yml)\n\nMarksmith is a GitHub-style markdown editor for Rails apps.\n\nIt supports Active Storage attachments and comes with a built-in markdown preview renderer.\n\n![Marksmith logo](./marksmith.png)\n\n![Marksmith demo](./marksmith.gif)\n\n\u003e [!WARNING]\n\u003e Marksmith is at the initial stage of development. It's nearing a beta release, but the API might change and bugs are expected. Please continue to use the library and report any issues in the GitHub repo.\n\nTemporary live demo here, under the description field: [https://main.avodemo.com/avo/resources/projects/new](https://main.avodemo.com/avo/resources/projects/new)\n\n## Usage\n\n```erb\n\u003c%= marksmith_tag :body %\u003e\n```\n\n## Installation\n\n#### 1. Add `marksmith` to your `Gemfile`\n\nHave Bundler add it by running this command:\n\n```bash\nbundle add marksmith commonmarker\n```\n\nOr manually install it.\n\nAdd this line to your application's Gemfile:\n\n```ruby\n# Gemfile\ngem \"marksmith\"\n# Add a markdown parser\ngem \"commonmarker\"\n```\n\n#### 2. Install the NPM package to import the StimulusJS controller.\n\nInstall the package from npmjs.org.\n\n```bash\n$ yarn add @avo-hq/marksmith\n```\n\nOr pin it using importmap.\n\n```bash\nbin/importmap pin @avo-hq/marksmith\n```\n\nImport and register the controllers in your application. The `ListContinuationController` is optional and only needed if you want to have continued lists in your markdown.\n\n```js\nimport { MarksmithController, ListContinuationController } from '@avo-hq/marksmith'\n\napplication.register('marksmith', MarksmithController)\napplication.register('list-continuation', ListContinuationController)\n```\n\n\u003e [!NOTE]\n\u003e Marksmith comes bundled with a few dependencies by default.\n\u003e If you want to manually import those dependencies and import only the controller from the package use the `/controller` path.\n\n```js\n// Manually import Marksmith's dependencies\nimport '@github/markdown-toolbar-element'\nimport { DirectUpload } from '@rails/activestorage'\nimport { post } from '@rails/request.js'\nimport { subscribe } from '@github/paste-markdown'\n\n// Import just the controller\nimport { MarksmithController } from '@avo-hq/marksmith/core'\n\napplication.register('marksmith', MarksmithController)\n```\n\n#### 3. Add the style tag to your `application.html` layout\n\n```erb\n\u003c%= stylesheet_link_tag \"marksmith\" %\u003e\n```\n\n#### 4. Use it\n\nUse a form helper tag or attach it to your form builder.\n\n```erb\n\u003c%= marksmith_tag :body, value: \"### This is important\" %\u003e\nor\n\u003c%= form.marksmith :body %\u003e\n```\n\n## Configuration\n\nMarksmith accepts a few configuration options.\n\n### Field options\n\nThe field supports a few of the regular options like `disabled`, `placeholder`, `autofocus`, `style`, `class`, `data`, and `value`, but also a custom one.\n\n`extra_preview_params` - Sends extra params to the preview renderer.\n\n`enable_file_uploads` - Whether to enable file uploads.\n\n`upload_url` - The URL to use for file uploads. If not provided, the editor will use the `rails_direct_uploads_url` helper.\n\n```erb\n\u003c%= marksmith_tag :body,\n  disabled: true,\n  placeholder: \"Write your best markdown here.\",\n  extra_preview_params: { foo: \"bar\" },\n  enable_file_uploads: true,\n  upload_url: nil\n  %\u003e\n```\n\n### Eject configuration file\n\nMarksmith comes with a default configuration file that you can eject to your app.\n\n```bash\nbin/rails generate marksmith:install\n```\n\nThis will create a `config/initializers/marksmith.rb` file in your app.\n\n### Mount path\n\nThe engine is mounted by default at `/marksmith`. You can change it by setting `Marksmith.configuration.mount_path` to a different path.\n\n```ruby\n# config/initializers/marksmith.rb\nMarksmith.configure do |config|\n  config.mount_path = \"/markdown\"\nend\n```\n\n### Mounting the engine\n\nThe engine is mounted by default, but you can disable it by setting `Marksmith.configuration.automatically_mount_engine` to `false` and then manually mount the engine in your `routes.rb` file.\n\n```ruby\n# config/routes.rb\nRails.application.routes.draw do\n  mount Marksmith::Engine =\u003e Marksmith.configuration.mount_path\nend\n```\n\n## Built-in preview renderer\n\nThe renderer is powered by [`Commonmarker`](https://github.com/gjtorikian/commonmarker) by default but it can be changed to [`Redcarpet`](https://github.com/vmg/redcarpet) or ['kramdown'](https://github.com/gettalong/kramdown) in the configuration or add your own logic by customizing the `Marksmith::Renderer` model.\nIt supports basic styles like headings, `strong`, `italic` and others.\n\nIn your `show.html.erb` view or the place where you want to render the compiled markup use the `marksmithed` helper and it will run the content through the renderer.\n\n```erb\n\u003c%== marksmithed post.body %\u003e\n```\n\n\u003e [!WARNING]\n\u003e Using the `\u003c%==` tag will output the raw HTML, so ensure you sanitize the content to avoid XSS attacks.\n\u003e\n\u003e See how we do it [here](app/views/marksmith/shared/_rendered_body.html.erb#L2).\n\u003e ```ruby\n\u003e # sample sanitization\n\u003e sanitize(body, tags: %w(table th tr td span) + ActionView::Helpers::SanitizeHelper.sanitizer_vendor.safe_list_sanitizer.allowed_tags.to_a)\n\u003e ```\n\n## Customize the renderer\n\nMarksmith comes with a default renderer that uses `commonmarker` by default but it can be changed to `redcarpet` or `kramdown` in the configuration.\n\n```ruby\n# config/initializers/marksmith.rb\nMarksmith.configure do |config|\n  config.parser = \"redcarpet\"\nend\n```\n\n### Add your own renderer\n\nYou can completely customize the renderer by overriding the `Marksmith::Renderer` model.\n\n```ruby\n# app/models/marksmith/renderer.rb\nmodule Marksmith\n  class Renderer\n    def initialize(body:)\n      @body = body\n    end\n\n    def render\n      # Your custom renderer logic here\n    end\n  end\nend\n```\n\n## Active Storage\n\nThe editor supports [ActiveStorage](https://guides.rubyonrails.org/active_storage_overview.html) uploads using drag and drop and pasting files into the field.\n\nWhe used in Avo it supports injecting assets using the [Media Library feature](http://docs.avohq.io/3.0/media-library.html).\n\n\n## List Continuation\n\nMarksmith has this great opt-in feature where you can have your lists continued.\nWe need to add the `ListContinuation` controller too.\n\n```js\nimport { ListContinuationController, MarksmithController } from '@avo-hq/marksmith'\n// or /core for the no-dependencies version\nimport { ListContinuationController, MarksmithController } from '@avo-hq/marksmith/core'\n\napplication.register('marksmith', MarksmithController)\napplication.register('list-continuation', ListContinuationController)\n```\n\n## Dark mode\n\nMarksmith comes with dark mode built in using the `.dark` class on a wrapper element strategy.\n\n```erb\n\u003c!-- Wrapper element --\u003e\n\u003cdiv class=\"dark\"\u003e\n  \u003c%= marksmith_tag :body %\u003e\n\u003c/div\u003e\n\n\u003c!-- or --\u003e\n\u003c%= form_with model: post, class: \"dark\" do |form| %\u003e\n  \u003c%= form.marksmith :body %\u003e\n\u003c% end %\u003e\n\n\u003c!-- or --\u003e\n\u003chtml class=\"dark\"\u003e\n  \u003c%= marksmith_tag :body %\u003e\n\u003c/html\u003e\n```\n\n## Who uses Marksmith?\n\n- [Avo](https://avohq.io) - Ruby on Rails Code-Based App Builder Framework\n\n*Open a PR and add your project here*\n\n## Contributing\n\nContribution directions go here.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Usage in Avo\n\nMarksmith work wonderfully in Avo throught the default [markdown field](https://docs.avohq.io/3.0/fields/markdown.html).\n\n## Other Open-Source Work\n\n- [`active_storage-blurhash`](https://github.com/avo-hq/active_storage-blurhash) - A plug-n-play [blurhash](https://blurha.sh/) integration for images stored in ActiveStorage\n- [`avo`](https://github.com/avo-hq/avo) - Build Internal Tools with Ruby on Rails\n- [`class_variants`](https://github.com/avo-hq/class_variants) - Easily configure styles and apply them as classes. Very useful when you're implementing Tailwind CSS components and call them with different states.\n- [`prop_initializer`](https://github.com/avo-hq/prop_initializer) - A flexible tool for defining properties on Ruby classes.\n- [`stimulus-confetti`](https://github.com/avo-hq/stimulus-confetti) - The easiest way to add confetti to your StimulusJS app\n\n## Try Avo ⭐️\n\nIf you enjoyed this gem try out [Avo](https://github.com/avo-hq/avo). It doubles your engineering speed without hiring extra developers. Teams build Internal Tools, Admin Panels, Content Management Systems, CRMs, and other types of Business Apps 10x faster on top of Ruby on Rails using Avo.\n\n## Troubleshooting\n\nIf you ever get a 431 error from Vite, clear your brower's cache for `localhost` (chrome://settings/content/all?searchSubpage=localhost).\n\n## Releasing\n\nRun `bin/release x.y.z`, use `--dry` to skip publishing. This is not idempotent. If releasing fails, take note of where the process left off and continue manually.\n\n### Details\n\nIn development we use `vite-rails` to compile and reload JS \u0026 CSS changes.\n\nWhen releasing we use `rollup` to compile the StimulusJS controller and `@tailwindcss/cli` to compile the CSS.\n\nThe JS code is pushed to npmjs.org on `@avo-hq/marksmith` and the CSS file is shipped in the gem.\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favo-hq%2Fmarksmith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favo-hq%2Fmarksmith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favo-hq%2Fmarksmith/lists"}