marksmith 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62a833a3db7da2729cbe8743021710f452973784d3ce79d6612dc37201df3532
4
- data.tar.gz: 192191de6e129b9ee26ef2fe7866efdf9d3e2cecd3d6448b8f3255847d1054e4
3
+ metadata.gz: 5018de3478a97ddcec156c4245851720d0ea86d36a2002ab82ba9a145f6739cc
4
+ data.tar.gz: 7fb9f7f2a8f702abad17476695f14bf65669af942609c2dffe1531bb71137f30
5
5
  SHA512:
6
- metadata.gz: 872a14aa320e5411628800c95c1ee9a2cb10a1e323af2d893c815fc075b3760f7d302c1410c47c09610828d444a6fde62129b2c8ab9d79127781cca77ea5a602
7
- data.tar.gz: cc6358f58b2136dd31e1742bd92d210142eb44e93eaa65376541ed04d6beba08c7b963156de0092777613ec6c2892d90315d3e424b84f01ca45732d4182ce798
6
+ metadata.gz: 813d6e4f66ac1a41c20afc5d1d6815d8695163badf4cb45ddbf49a1da394eb3c9436677610a61bf00bbf67e961abab9a6e5b89b1ccf61f203d82650d36f97292
7
+ data.tar.gz: 10b74b2a3af7f5ee6ecea2d76d54efe3d91d9784c4f3bd38ba807a828f36a79ae722deaab0285c8b9027660b452380f35df2b84af945971b85ed7199a4bd3a91
data/README.md CHANGED
@@ -8,6 +8,11 @@ It supports Active Storage attachments and comes with a built-in mardown preview
8
8
 
9
9
  ![Marksmith demo](./marksmith.gif)
10
10
 
11
+ > [!WARNING]
12
+ > 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.
13
+
14
+ Temporary live demo here, under the description field: [https://main.avodemo.com/avo/resources/projects/new](https://main.avodemo.com/avo/resources/projects/new)
15
+
11
16
  ## Usage
12
17
 
13
18
  ```erb
@@ -16,7 +21,7 @@ It supports Active Storage attachments and comes with a built-in mardown preview
16
21
 
17
22
  ## Installation
18
23
 
19
- ### 1. Add `marksmith` to your `Gemfile`
24
+ #### 1. Add `marksmith` to your `Gemfile`
20
25
 
21
26
  Have Bundler add it by running this command:
22
27
 
@@ -33,20 +38,27 @@ Add this line to your application's Gemfile:
33
38
  gem "marksmith"
34
39
  ```
35
40
 
36
- ### 2. Install the NPM package to import the StimulusJS controller.
41
+ #### 2. Install the NPM package to import the StimulusJS controller.
37
42
 
38
- Install the package.
43
+ Install the package from npmjs.org.
39
44
 
40
45
  ```bash
41
46
  $ yarn add @avo-hq/marksmith
42
47
  ```
43
48
 
44
- Import and register it in your application.
49
+ Or pin it using importmap.
50
+
51
+ ```bash
52
+ bin/importmap pin @avo-hq/marksmith
53
+ ```
54
+
55
+ Import and register the controllers in your application. The `ListContinuationController` is optional and only needed if you want to have continued lists in your markdown.
45
56
 
46
57
  ```js
47
- import { MarksmithController } from '@avo-hq/marksmith'
58
+ import { MarksmithController, ListContinuationController } from '@avo-hq/marksmith'
48
59
 
49
60
  application.register('marksmith', MarksmithController)
61
+ application.register('list-continuation', ListContinuationController)
50
62
  ```
51
63
 
52
64
  > [!NOTE]
@@ -66,28 +78,78 @@ import { MarksmithController } from '@avo-hq/marksmith/core'
66
78
  application.register('marksmith', MarksmithController)
67
79
  ```
68
80
 
69
- ### 3. Add the style tag to your `application.html` layout
81
+ #### 3. Add the style tag to your `application.html` layout
70
82
 
71
83
  ```erb
72
84
  <%= stylesheet_link_tag "marksmith" %>
73
85
  ```
74
86
 
75
- ### 4. Use it
87
+ #### 4. Use it
76
88
 
77
89
  Use a form helper tag or attach it to your form builder.
78
90
 
79
91
  ```erb
80
92
  <%= marksmith_tag :body, value: "### This is important" %>
81
93
  or
82
- <%= @form.marksmith :body %>
94
+ <%= form.marksmith :body %>
83
95
  ```
84
96
 
85
- ## Options
97
+ ## Configuration
98
+
99
+ Marksmith accepts a few configuration options.
100
+
101
+ ### Field options
86
102
 
87
103
  The field supports a few of the regular options like `disabled`, `placeholder`, `autofocus`, `style`, `class`, `rows`, `data`, and `value`, but also a custom one.
88
104
 
89
105
  `extra_preview_params` - Sends extra params to the preview renderer.
90
106
 
107
+ `enable_file_uploads` - Whether to enable file uploads.
108
+
109
+ `upload_url` - The URL to use for file uploads. If not provided, the editor will use the `rails_direct_uploads_url` helper.
110
+
111
+ ```erb
112
+ <%= marksmith_tag :body,
113
+ disabled: true,
114
+ placeholder: "Write your best markdown here.",
115
+ extra_preview_params: { foo: "bar" },
116
+ enable_file_uploads: true,
117
+ upload_url: nil
118
+ %>
119
+ ```
120
+
121
+ ### Eject configuration file
122
+
123
+ Marksmith comes with a default configuration file that you can eject to your app.
124
+
125
+ ```bash
126
+ bin/rails generate marksmith:install
127
+ ```
128
+
129
+ This will create a `config/initializers/marksmith.rb` file in your app.
130
+
131
+ ### Mount path
132
+
133
+ The engine is mounted by default at `/marksmith`. You can change it by setting `Marksmith.configuration.mount_path` to a different path.
134
+
135
+ ```ruby
136
+ # config/initializers/marksmith.rb
137
+ Marksmith.configure do |config|
138
+ config.mount_path = "/markdown"
139
+ end
140
+ ```
141
+
142
+ ### Mounting the engine
143
+
144
+ The 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.
145
+
146
+ ```ruby
147
+ # config/routes.rb
148
+ Rails.application.routes.draw do
149
+ mount Marksmith::Engine => Marksmith.configuration.mount_path
150
+ end
151
+ ```
152
+
91
153
  ## Built-in preview renderer
92
154
 
93
155
  The renderer is powered by [`Redcarpet`](https://github.com/vmg/redcarpet).
@@ -96,16 +158,18 @@ It supports basic styles for headings, `strong`, `italic` and others.
96
158
  In 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.
97
159
 
98
160
  ```erb
99
- <%= marksmithed post.body %>
161
+ <%== marksmithed post.body %>
100
162
  ```
101
163
 
102
- ## Using with importmap
164
+ > [!WARNING]
165
+ > Using the `<%==` tag will output the raw HTML, so ensure you sanitize the content to avoid XSS attacks.
166
+ >
167
+ > See how we do it [here](https://github.com/avo-hq/avo/blob/main/app/views/marksmith/shared/_rendered_body.html.erb#L2).
168
+ > ```ruby
169
+ > # sample sanitization
170
+ > sanitize(body, tags: %w(table th tr td span) + ActionView::Helpers::SanitizeHelper.sanitizer_vendor.safe_list_sanitizer.allowed_tags.to_a)
171
+ > ```
103
172
 
104
- It should be as simple as running this command and have it pinned in your `importmap.rb` file.
105
-
106
- ```bash
107
- bin/importmap pin @avo-hq/marksmith
108
- ```
109
173
 
110
174
  ## Active Storage
111
175
 
@@ -128,6 +192,12 @@ application.register('marksmith', MarksmithController)
128
192
  application.register('list-continuation', ListContinuationController)
129
193
  ```
130
194
 
195
+ ## Who uses Marksmith?
196
+
197
+ - [Avo](https://avohq.io) - Ruby on Rails Code-Based App Builder Framework
198
+
199
+ *Open a PR and add your project here*
200
+
131
201
  ## Contributing
132
202
 
133
203
  Contribution directions go here.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Marksmith 0.1.1
2
+ Marksmith 0.1.2
3
3
  */
4
4
  var ListContinuationController = (function () {
5
5
  'use strict';
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Marksmith 0.1.1
2
+ Marksmith 0.1.2
3
3
  */
4
4
  var ListContinuationController = (function (stimulus) {
5
5
  'use strict';
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Marksmith 0.1.1
2
+ Marksmith 0.1.2
3
3
  */
4
4
  var MarksmithController = (function () {
5
5
  'use strict';
@@ -2827,10 +2827,15 @@ var MarksmithController = (function () {
2827
2827
  fieldId: String,
2828
2828
  galleryEnabled: { type: Boolean, default: false },
2829
2829
  galleryOpenPath: String,
2830
+ fileUploadsEnabled: { type: Boolean, default: true },
2830
2831
  }
2831
2832
 
2832
2833
  static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
2833
2834
 
2835
+ get #fileUploadsDisabled() {
2836
+ return !this.fileUploadsEnabledValue
2837
+ }
2838
+
2834
2839
  connect() {
2835
2840
  subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } });
2836
2841
  }
@@ -2878,11 +2883,15 @@ var MarksmithController = (function () {
2878
2883
  }
2879
2884
 
2880
2885
  dropUpload(event) {
2886
+ if (this.#fileUploadsDisabled) return
2887
+
2881
2888
  event.preventDefault();
2882
2889
  this.#uploadFiles(event.dataTransfer.files);
2883
2890
  }
2884
2891
 
2885
2892
  pasteUpload(event) {
2893
+ if (this.#fileUploadsDisabled) return
2894
+
2886
2895
  if (!event.clipboardData.files.length) return
2887
2896
 
2888
2897
  event.preventDefault();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Marksmith 0.1.1
2
+ Marksmith 0.1.2
3
3
  */
4
4
  var MarksmithController = (function (stimulus) {
5
5
  'use strict';
@@ -2337,10 +2337,15 @@ var MarksmithController = (function (stimulus) {
2337
2337
  fieldId: String,
2338
2338
  galleryEnabled: { type: Boolean, default: false },
2339
2339
  galleryOpenPath: String,
2340
+ fileUploadsEnabled: { type: Boolean, default: true },
2340
2341
  }
2341
2342
 
2342
2343
  static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
2343
2344
 
2345
+ get #fileUploadsDisabled() {
2346
+ return !this.fileUploadsEnabledValue
2347
+ }
2348
+
2344
2349
  connect() {
2345
2350
  subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } });
2346
2351
  }
@@ -2388,11 +2393,15 @@ var MarksmithController = (function (stimulus) {
2388
2393
  }
2389
2394
 
2390
2395
  dropUpload(event) {
2396
+ if (this.#fileUploadsDisabled) return
2397
+
2391
2398
  event.preventDefault();
2392
2399
  this.#uploadFiles(event.dataTransfer.files);
2393
2400
  }
2394
2401
 
2395
2402
  pasteUpload(event) {
2403
+ if (this.#fileUploadsDisabled) return
2404
+
2396
2405
  if (!event.clipboardData.files.length) return
2397
2406
 
2398
2407
  event.preventDefault();
@@ -17,10 +17,15 @@ export default class extends Controller {
17
17
  fieldId: String,
18
18
  galleryEnabled: { type: Boolean, default: false },
19
19
  galleryOpenPath: String,
20
+ fileUploadsEnabled: { type: Boolean, default: true },
20
21
  }
21
22
 
22
23
  static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']
23
24
 
25
+ get #fileUploadsDisabled() {
26
+ return !this.fileUploadsEnabledValue
27
+ }
28
+
24
29
  connect() {
25
30
  subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } })
26
31
  }
@@ -68,11 +73,15 @@ export default class extends Controller {
68
73
  }
69
74
 
70
75
  dropUpload(event) {
76
+ if (this.#fileUploadsDisabled) return
77
+
71
78
  event.preventDefault()
72
79
  this.#uploadFiles(event.dataTransfer.files)
73
80
  }
74
81
 
75
82
  pasteUpload(event) {
83
+ if (this.#fileUploadsDisabled) return
84
+
76
85
  if (!event.clipboardData.files.length) return
77
86
 
78
87
  event.preventDefault()
@@ -13,6 +13,20 @@
13
13
  local_assigns[:value] || nil
14
14
  end
15
15
  extra_preview_params = local_assigns[:extra_preview_params] || {}
16
+ upload_url = if local_assigns[:upload_url].present?
17
+ local_assigns[:upload_url]
18
+ elsif defined?(ActiveStorage)
19
+ main_app.rails_direct_uploads_url
20
+ end
21
+
22
+ enable_file_uploads = if upload_url.blank?
23
+ false
24
+ elsif local_assigns[:enable_file_uploads].nil?
25
+ true
26
+ else
27
+ local_assigns[:enable_file_uploads]
28
+ end
29
+
16
30
 
17
31
  # Used by Avo and other adapters to enable the gallery link.
18
32
  gallery_enabled = local_assigns.dig(:gallery, :enabled) || false
@@ -35,8 +49,9 @@
35
49
  ",
36
50
  unique_selector: ".#{@input_id}", # used to pinpoint the exact element in which to insert the attachment
37
51
  marksmith_preview_url_value: marksmith.markdown_previews_path,
52
+ marksmith_file_uploads_enabled_value: enable_file_uploads,
38
53
  marksmith_active_tab_class: "bg-white",
39
- marksmith_attach_url_value: main_app.rails_direct_uploads_url,
54
+ marksmith_attach_url_value: upload_url,
40
55
  marksmith_extra_preview_params_value: extra_preview_params.as_json,
41
56
  **local_assigns.fetch(:controller_data_attributes, {})
42
57
  } do %>
@@ -85,8 +100,10 @@
85
100
  <%= link_to "https://docs.github.com/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax", target: "_blank", class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
86
101
  <%= image_tag asset_path("marksmith/svgs/markdown.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.markdown_is_supported").humanize %>
87
102
  <% end %>
88
- <%= button_tag data: { action: "click->marksmith#buttonUpload" }, class: class_names("ms:bg-none ms:border-none ms:bg-transparent ms:text-neutral-600 ms:items-center ms:flex", toolbar_button_classes) do %>
89
- <%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.upload_files").humanize %>
103
+ <% if enable_file_uploads %>
104
+ <%= button_tag data: { action: "click->marksmith#buttonUpload" }, class: class_names("ms:bg-none ms:border-none ms:bg-transparent ms:text-neutral-600 ms:items-center ms:flex", toolbar_button_classes) do %>
105
+ <%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.upload_files").humanize %>
106
+ <% end %>
90
107
  <% end %>
91
108
  <% if gallery_enabled %>
92
109
  <%= link_to gallery_full_path, data: { turbo_frame: gallery_turbo_frame }, class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
@@ -0,0 +1,15 @@
1
+ require "rails/generators"
2
+
3
+ module Marksmith
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Creates a Marksmith initializer."
9
+
10
+ def create_initializer_file
11
+ template "initializer/marksmith.tt", "config/initializers/marksmith.rb"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ # Marksmith.configure do |config|
2
+ # config.automatically_mount_engine = true
3
+ # config.mount_path = "/marksmith"
4
+ # end
@@ -0,0 +1,16 @@
1
+ module Marksmith
2
+ class Configuration
3
+ include ActiveSupport::Configurable
4
+
5
+ config_accessor(:automatically_mount_engine) { true }
6
+ config_accessor(:mount_path) { "/marksmith" }
7
+ end
8
+
9
+ def self.configuration
10
+ @configuration ||= Configuration.new
11
+ end
12
+
13
+ def self.configure
14
+ yield configuration
15
+ end
16
+ end
@@ -17,6 +17,14 @@ module Marksmith
17
17
  end
18
18
  end
19
19
 
20
+ initializer "marksmith.routes" do |app|
21
+ if Marksmith.configuration.automatically_mount_engine
22
+ app.routes.append do
23
+ mount Marksmith::Engine => Marksmith.configuration.mount_path
24
+ end
25
+ end
26
+ end
27
+
20
28
  initializer "marksmith.assets.precompile" do |app|
21
29
  if Rails.application.config.respond_to?(:assets)
22
30
  # The manifest will expose the asset files to the main app.
@@ -24,14 +32,14 @@ module Marksmith
24
32
  end
25
33
  end
26
34
 
35
+ generators do |app|
36
+ Rails::Generators.configure! app.config.generators
37
+ end
38
+
27
39
  initializer "avo-markdown_field.init" do |app|
28
40
  if defined?(Avo)
29
41
  require "marksmith/fields/markdown_field"
30
42
 
31
- app.routes.append do
32
- mount Marksmith::Engine => "/marksmith"
33
- end
34
-
35
43
  ActiveSupport.on_load(:avo_boot) do
36
44
  Avo.plugin_manager.register :marksmith_field
37
45
 
@@ -1,3 +1,3 @@
1
1
  module Marksmith
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/marksmith.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "marksmith/version"
2
+ require "marksmith/configuration"
2
3
  require "marksmith/engine"
3
4
 
4
5
  module Marksmith
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marksmith
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Marin
@@ -11,19 +11,19 @@ cert_chain: []
11
11
  date: 2025-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.0
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: redcarpet
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -96,7 +96,10 @@ files:
96
96
  - config/locales/marksmith.en.yml
97
97
  - config/routes.rb
98
98
  - config/vite.json
99
+ - lib/generators/marksmith/install_generator.rb
100
+ - lib/generators/marksmith/templates/initializer/marksmith.tt
99
101
  - lib/marksmith.rb
102
+ - lib/marksmith/configuration.rb
100
103
  - lib/marksmith/engine.rb
101
104
  - lib/marksmith/fields/markdown_field.rb
102
105
  - lib/marksmith/helper.rb
@@ -124,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
127
  - !ruby/object:Gem::Version
125
128
  version: '0'
126
129
  requirements: []
127
- rubygems_version: 3.5.9
130
+ rubygems_version: 3.5.22
128
131
  signing_key:
129
132
  specification_version: 4
130
133
  summary: Marksmith is a GitHub-style markdown editor for Ruby on Rails applications.