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 +4 -4
- data/README.md +86 -16
- data/app/assets/javascripts/list_continuation_controller-full.esm.js +1 -1
- data/app/assets/javascripts/list_continuation_controller-no-stimulus.esm.js +1 -1
- data/app/assets/javascripts/marksmith_controller-full.esm.js +10 -1
- data/app/assets/javascripts/marksmith_controller-no-stimulus.esm.js +10 -1
- data/app/frontend/entrypoints/javascript/controllers/marksmith_controller.js +9 -0
- data/app/views/marksmith/shared/_editor.html.erb +20 -3
- data/lib/generators/marksmith/install_generator.rb +15 -0
- data/lib/generators/marksmith/templates/initializer/marksmith.tt +4 -0
- data/lib/marksmith/configuration.rb +16 -0
- data/lib/marksmith/engine.rb +12 -4
- data/lib/marksmith/version.rb +1 -1
- data/lib/marksmith.rb +1 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5018de3478a97ddcec156c4245851720d0ea86d36a2002ab82ba9a145f6739cc
|
4
|
+
data.tar.gz: 7fb9f7f2a8f702abad17476695f14bf65669af942609c2dffe1531bb71137f30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|

|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
<%=
|
94
|
+
<%= form.marksmith :body %>
|
83
95
|
```
|
84
96
|
|
85
|
-
##
|
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
|
-
|
161
|
+
<%== marksmithed post.body %>
|
100
162
|
```
|
101
163
|
|
102
|
-
|
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.
|
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.
|
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:
|
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
|
-
|
89
|
-
<%=
|
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,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
|
data/lib/marksmith/engine.rb
CHANGED
@@ -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
|
|
data/lib/marksmith/version.rb
CHANGED
data/lib/marksmith.rb
CHANGED
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.
|
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:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
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:
|
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.
|
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.
|