inkpen 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.rubocop.yml +8 -0
  4. data/.yardopts +11 -0
  5. data/CLAUDE.md +141 -0
  6. data/README.md +409 -0
  7. data/Rakefile +19 -0
  8. data/app/assets/javascripts/inkpen/controllers/editor_controller.js +2050 -0
  9. data/app/assets/javascripts/inkpen/controllers/sticky_toolbar_controller.js +667 -0
  10. data/app/assets/javascripts/inkpen/controllers/toolbar_controller.js +693 -0
  11. data/app/assets/javascripts/inkpen/export/html.js +637 -0
  12. data/app/assets/javascripts/inkpen/export/index.js +30 -0
  13. data/app/assets/javascripts/inkpen/export/markdown.js +697 -0
  14. data/app/assets/javascripts/inkpen/export/pdf.js +372 -0
  15. data/app/assets/javascripts/inkpen/extensions/advanced_table.js +640 -0
  16. data/app/assets/javascripts/inkpen/extensions/block_commands.js +300 -0
  17. data/app/assets/javascripts/inkpen/extensions/block_gutter.js +338 -0
  18. data/app/assets/javascripts/inkpen/extensions/callout.js +303 -0
  19. data/app/assets/javascripts/inkpen/extensions/columns.js +403 -0
  20. data/app/assets/javascripts/inkpen/extensions/database.js +990 -0
  21. data/app/assets/javascripts/inkpen/extensions/document_section.js +352 -0
  22. data/app/assets/javascripts/inkpen/extensions/drag_handle.js +407 -0
  23. data/app/assets/javascripts/inkpen/extensions/embed.js +629 -0
  24. data/app/assets/javascripts/inkpen/extensions/enhanced_image.js +566 -0
  25. data/app/assets/javascripts/inkpen/extensions/export_commands.js +271 -0
  26. data/app/assets/javascripts/inkpen/extensions/file_attachment.js +593 -0
  27. data/app/assets/javascripts/inkpen/extensions/inkpen_table/index.js +58 -0
  28. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table.js +638 -0
  29. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table_cell.js +100 -0
  30. data/app/assets/javascripts/inkpen/extensions/inkpen_table/inkpen_table_header.js +100 -0
  31. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_constants.js +152 -0
  32. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_helpers.js +254 -0
  33. data/app/assets/javascripts/inkpen/extensions/inkpen_table/table_menu.js +282 -0
  34. data/app/assets/javascripts/inkpen/extensions/preformatted.js +239 -0
  35. data/app/assets/javascripts/inkpen/extensions/section.js +281 -0
  36. data/app/assets/javascripts/inkpen/extensions/section_title.js +126 -0
  37. data/app/assets/javascripts/inkpen/extensions/slash_commands.js +439 -0
  38. data/app/assets/javascripts/inkpen/extensions/table_of_contents.js +474 -0
  39. data/app/assets/javascripts/inkpen/extensions/toggle_block.js +332 -0
  40. data/app/assets/javascripts/inkpen/index.js +87 -0
  41. data/app/assets/stylesheets/inkpen/advanced_table.css +514 -0
  42. data/app/assets/stylesheets/inkpen/animations.css +626 -0
  43. data/app/assets/stylesheets/inkpen/block_gutter.css +265 -0
  44. data/app/assets/stylesheets/inkpen/callout.css +359 -0
  45. data/app/assets/stylesheets/inkpen/columns.css +314 -0
  46. data/app/assets/stylesheets/inkpen/database.css +658 -0
  47. data/app/assets/stylesheets/inkpen/document_section.css +305 -0
  48. data/app/assets/stylesheets/inkpen/drag_drop.css +220 -0
  49. data/app/assets/stylesheets/inkpen/editor.css +652 -0
  50. data/app/assets/stylesheets/inkpen/embed.css +468 -0
  51. data/app/assets/stylesheets/inkpen/enhanced_image.css +453 -0
  52. data/app/assets/stylesheets/inkpen/export.css +499 -0
  53. data/app/assets/stylesheets/inkpen/file_attachment.css +347 -0
  54. data/app/assets/stylesheets/inkpen/footnotes.css +136 -0
  55. data/app/assets/stylesheets/inkpen/inkpen_table.css +608 -0
  56. data/app/assets/stylesheets/inkpen/preformatted.css +215 -0
  57. data/app/assets/stylesheets/inkpen/search_replace.css +58 -0
  58. data/app/assets/stylesheets/inkpen/section.css +236 -0
  59. data/app/assets/stylesheets/inkpen/slash_menu.css +252 -0
  60. data/app/assets/stylesheets/inkpen/sticky_toolbar.css +314 -0
  61. data/app/assets/stylesheets/inkpen/toc.css +386 -0
  62. data/app/assets/stylesheets/inkpen/toggle.css +260 -0
  63. data/app/helpers/inkpen/editor_helper.rb +114 -0
  64. data/app/views/inkpen/_editor.html.erb +139 -0
  65. data/config/importmap.rb +170 -0
  66. data/docs/.DS_Store +0 -0
  67. data/docs/CHANGELOG.md +571 -0
  68. data/docs/FEATURES.md +436 -0
  69. data/docs/ROADMAP.md +3029 -0
  70. data/docs/VISION.md +235 -0
  71. data/docs/extensions/INKPEN_TABLE.md +482 -0
  72. data/docs/thinking/CORRECTED_NO_VUE.md +756 -0
  73. data/docs/thinking/EXECUTIVE_SUMMARY.md +403 -0
  74. data/docs/thinking/INKPEN_CODE_SAMPLES.md +1479 -0
  75. data/docs/thinking/INKPEN_MASTER_GUIDE.md +891 -0
  76. data/docs/thinking/README_START_HERE.md +341 -0
  77. data/lib/inkpen/configuration.rb +175 -0
  78. data/lib/inkpen/editor.rb +204 -0
  79. data/lib/inkpen/engine.rb +32 -0
  80. data/lib/inkpen/extensions/base.rb +109 -0
  81. data/lib/inkpen/extensions/code_block_syntax.rb +177 -0
  82. data/lib/inkpen/extensions/document_section.rb +111 -0
  83. data/lib/inkpen/extensions/forced_document.rb +183 -0
  84. data/lib/inkpen/extensions/mention.rb +155 -0
  85. data/lib/inkpen/extensions/preformatted.rb +111 -0
  86. data/lib/inkpen/extensions/section.rb +139 -0
  87. data/lib/inkpen/extensions/slash_commands.rb +100 -0
  88. data/lib/inkpen/extensions/table.rb +182 -0
  89. data/lib/inkpen/extensions/task_list.rb +145 -0
  90. data/lib/inkpen/sticky_toolbar.rb +157 -0
  91. data/lib/inkpen/toolbar.rb +145 -0
  92. data/lib/inkpen/version.rb +5 -0
  93. data/lib/inkpen.rb +101 -0
  94. data/sig/inkpen.rbs +4 -0
  95. metadata +165 -0
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Inkpen
4
+ module Extensions
5
+ ##
6
+ # Task List extension for TipTap.
7
+ #
8
+ # Enables interactive checkbox/task list functionality. Users can
9
+ # create todo lists with checkable items that persist their state.
10
+ #
11
+ # @example Basic usage
12
+ # extension = Inkpen::Extensions::TaskList.new
13
+ #
14
+ # @example With nested tasks disabled
15
+ # extension = Inkpen::Extensions::TaskList.new(
16
+ # nested: false,
17
+ # item_class: "my-task-item"
18
+ # )
19
+ #
20
+ # @see https://tiptap.dev/docs/examples/tasks
21
+ # @author Inkpen Team
22
+ # @since 0.2.0
23
+ #
24
+ class TaskList < Base
25
+ ##
26
+ # The unique name of this extension.
27
+ #
28
+ # @return [Symbol] :task_list
29
+ #
30
+ def name
31
+ :task_list
32
+ end
33
+
34
+ ##
35
+ # Whether task lists can be nested.
36
+ #
37
+ # @return [Boolean] true to allow nested task lists
38
+ #
39
+ def nested?
40
+ options.fetch(:nested, true)
41
+ end
42
+
43
+ ##
44
+ # CSS class applied to task list container.
45
+ #
46
+ # @return [String] CSS class name
47
+ #
48
+ def list_class
49
+ options.fetch(:list_class, "inkpen-task-list")
50
+ end
51
+
52
+ ##
53
+ # CSS class applied to individual task items.
54
+ #
55
+ # @return [String] CSS class name
56
+ #
57
+ def item_class
58
+ options.fetch(:item_class, "inkpen-task-item")
59
+ end
60
+
61
+ ##
62
+ # CSS class applied to checked task items.
63
+ #
64
+ # @return [String] CSS class name
65
+ #
66
+ def checked_class
67
+ options.fetch(:checked_class, "inkpen-task-checked")
68
+ end
69
+
70
+ ##
71
+ # CSS class applied to the checkbox element.
72
+ #
73
+ # @return [String] CSS class name
74
+ #
75
+ def checkbox_class
76
+ options.fetch(:checkbox_class, "inkpen-task-checkbox")
77
+ end
78
+
79
+ ##
80
+ # HTML attributes for the task list element.
81
+ #
82
+ # @return [Hash] HTML attributes
83
+ #
84
+ def html_attributes
85
+ options.fetch(:html_attributes, { class: list_class })
86
+ end
87
+
88
+ ##
89
+ # HTML attributes for task item elements.
90
+ #
91
+ # @return [Hash] HTML attributes
92
+ #
93
+ def item_html_attributes
94
+ options.fetch(:item_html_attributes, { class: item_class })
95
+ end
96
+
97
+ ##
98
+ # Whether clicking on the text toggles the checkbox.
99
+ #
100
+ # @return [Boolean] true if text click toggles checkbox
101
+ #
102
+ def text_toggle?
103
+ options.fetch(:text_toggle, false)
104
+ end
105
+
106
+ ##
107
+ # Keyboard shortcut to create a task list.
108
+ #
109
+ # @return [String] keyboard shortcut
110
+ #
111
+ def keyboard_shortcut
112
+ options.fetch(:keyboard_shortcut, "Mod-Shift-9")
113
+ end
114
+
115
+ ##
116
+ # Convert to configuration hash for JavaScript.
117
+ #
118
+ # @return [Hash] configuration for the TipTap extension
119
+ #
120
+ def to_config
121
+ {
122
+ nested: nested?,
123
+ listClass: list_class,
124
+ itemClass: item_class,
125
+ checkedClass: checked_class,
126
+ checkboxClass: checkbox_class,
127
+ HTMLAttributes: html_attributes,
128
+ itemHTMLAttributes: item_html_attributes,
129
+ textToggle: text_toggle?,
130
+ keyboardShortcut: keyboard_shortcut
131
+ }
132
+ end
133
+
134
+ private
135
+
136
+ def default_options
137
+ super.merge(
138
+ nested: true,
139
+ text_toggle: false,
140
+ keyboard_shortcut: "Mod-Shift-9"
141
+ )
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Inkpen
4
+ ##
5
+ # PORO representing sticky toolbar configuration.
6
+ #
7
+ # The StickyToolbar provides block and media insertion controls that
8
+ # remain fixed on screen. It's separate from the text formatting
9
+ # toolbar and focused on inserting new content blocks.
10
+ #
11
+ # Supports horizontal (bottom) and vertical (left/right) layouts.
12
+ #
13
+ # @example Basic bottom toolbar
14
+ # sticky_toolbar = Inkpen::StickyToolbar.new(position: :bottom)
15
+ #
16
+ # @example Custom buttons
17
+ # sticky_toolbar = Inkpen::StickyToolbar.new(
18
+ # position: :bottom,
19
+ # buttons: [:table, :code_block, :image, :divider]
20
+ # )
21
+ #
22
+ # @example In editor helper
23
+ # <%= inkpen_editor name: "post[body]",
24
+ # sticky_toolbar: Inkpen::StickyToolbar.new(position: :right) %>
25
+ #
26
+ # @see Inkpen::Toolbar For text formatting toolbar
27
+ #
28
+ # @author Nauman Tariq
29
+ # @since 0.2.1
30
+ #
31
+ class StickyToolbar
32
+ ##
33
+ # @!attribute [r] position
34
+ # @return [Symbol] toolbar position (:bottom, :left, :right)
35
+ #
36
+ # @!attribute [r] buttons
37
+ # @return [Array<Symbol>] list of toolbar buttons
38
+ #
39
+ # @!attribute [r] widget_types
40
+ # @return [Array<String>] available widget types for widget picker
41
+ #
42
+ attr_reader :position, :buttons, :widget_types
43
+
44
+ ##
45
+ # Valid toolbar positions.
46
+ # @return [Array<Symbol>]
47
+ POSITIONS = %i[bottom left right].freeze
48
+
49
+ ##
50
+ # Block insertion buttons.
51
+ # @return [Array<Symbol>]
52
+ BLOCK_BUTTONS = %i[table code_block blockquote horizontal_rule task_list].freeze
53
+
54
+ ##
55
+ # Media insertion buttons.
56
+ # @return [Array<Symbol>]
57
+ MEDIA_BUTTONS = %i[image youtube embed].freeze
58
+
59
+ ##
60
+ # Widget insertion buttons (opens modal picker).
61
+ # @return [Array<Symbol>]
62
+ WIDGET_BUTTONS = %i[widget].freeze
63
+
64
+ ##
65
+ # Preset with block buttons only.
66
+ # @return [Array<Symbol>]
67
+ PRESET_BLOCKS = BLOCK_BUTTONS.freeze
68
+
69
+ ##
70
+ # Preset with media buttons only.
71
+ # @return [Array<Symbol>]
72
+ PRESET_MEDIA = MEDIA_BUTTONS.freeze
73
+
74
+ ##
75
+ # Full preset with all buttons.
76
+ # @return [Array<Symbol>]
77
+ PRESET_FULL = (BLOCK_BUTTONS + MEDIA_BUTTONS + WIDGET_BUTTONS).freeze
78
+
79
+ ##
80
+ # Initialize a new sticky toolbar configuration.
81
+ #
82
+ # @param position [Symbol] toolbar position (:bottom, :left, :right)
83
+ # @param buttons [Array<Symbol>, nil] custom button list
84
+ # @param widget_types [Array<String>, nil] widget types for picker
85
+ # @param enabled [Boolean] whether the sticky toolbar is enabled
86
+ #
87
+ def initialize(position: :bottom, buttons: nil, widget_types: nil, enabled: true)
88
+ @position = validate_position(position)
89
+ @buttons = buttons || PRESET_FULL
90
+ @widget_types = widget_types || default_widget_types
91
+ @enabled = enabled
92
+ end
93
+
94
+ ##
95
+ # Check if the sticky toolbar is enabled.
96
+ #
97
+ # @return [Boolean] true if enabled
98
+ #
99
+ def enabled?
100
+ @enabled
101
+ end
102
+
103
+ ##
104
+ # Check if toolbar uses vertical layout (left or right).
105
+ #
106
+ # @return [Boolean] true if vertical
107
+ #
108
+ def vertical?
109
+ %i[left right].include?(position)
110
+ end
111
+
112
+ ##
113
+ # Check if toolbar uses horizontal layout (bottom).
114
+ #
115
+ # @return [Boolean] true if horizontal
116
+ #
117
+ def horizontal?
118
+ position == :bottom
119
+ end
120
+
121
+ ##
122
+ # Generate data attributes for Stimulus controller.
123
+ #
124
+ # @return [Hash] data attributes hash
125
+ #
126
+ def data_attributes
127
+ {
128
+ "inkpen--sticky-toolbar-position-value" => position.to_s,
129
+ "inkpen--sticky-toolbar-buttons-value" => buttons.to_json,
130
+ "inkpen--sticky-toolbar-widget-types-value" => widget_types.to_json,
131
+ "inkpen--sticky-toolbar-vertical-value" => vertical?.to_s
132
+ }
133
+ end
134
+
135
+ private
136
+
137
+ ##
138
+ # Validate and normalize position value.
139
+ #
140
+ # @param pos [Symbol, String] position to validate
141
+ # @return [Symbol] validated position
142
+ #
143
+ def validate_position(pos)
144
+ pos = pos.to_sym
145
+ POSITIONS.include?(pos) ? pos : :bottom
146
+ end
147
+
148
+ ##
149
+ # Default widget types for the widget picker.
150
+ #
151
+ # @return [Array<String>] widget type names
152
+ #
153
+ def default_widget_types
154
+ %w[form gallery poll]
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Inkpen
4
+ ##
5
+ # PORO representing toolbar configuration.
6
+ #
7
+ # The Toolbar class configures the floating or fixed toolbar that
8
+ # appears when text is selected (floating) or at the top of the
9
+ # editor (fixed).
10
+ #
11
+ # @example Basic floating toolbar
12
+ # toolbar = Inkpen::Toolbar.new(style: :floating)
13
+ #
14
+ # @example Custom button set
15
+ # toolbar = Inkpen::Toolbar.new(
16
+ # style: :fixed,
17
+ # buttons: [:bold, :italic, :link, :heading]
18
+ # )
19
+ #
20
+ # @example Using presets
21
+ # toolbar = Inkpen::Toolbar.new(
22
+ # style: :floating,
23
+ # buttons: Inkpen::Toolbar::PRESET_MINIMAL
24
+ # )
25
+ #
26
+ # @see Inkpen::StickyToolbar For block insertion toolbar
27
+ #
28
+ # @author Nauman Tariq
29
+ # @since 0.1.0
30
+ #
31
+ class Toolbar
32
+ ##
33
+ # @!attribute [r] style
34
+ # @return [Symbol] toolbar display style (:floating, :fixed, :none)
35
+ #
36
+ # @!attribute [r] buttons
37
+ # @return [Array<Symbol>] list of toolbar buttons
38
+ #
39
+ # @!attribute [r] position
40
+ # @return [Symbol] toolbar position (:top, :bottom)
41
+ #
42
+ attr_reader :style, :buttons, :position
43
+
44
+ ##
45
+ # Text formatting buttons (bold, italic, strike, underline).
46
+ # @return [Array<Symbol>]
47
+ FORMATTING_BUTTONS = %i[bold italic strike underline].freeze
48
+
49
+ ##
50
+ # Block-level formatting buttons.
51
+ # @return [Array<Symbol>]
52
+ BLOCK_BUTTONS = %i[heading bullet_list ordered_list blockquote code_block].freeze
53
+
54
+ ##
55
+ # Content insertion buttons.
56
+ # @return [Array<Symbol>]
57
+ INSERT_BUTTONS = %i[link image table horizontal_rule].freeze
58
+
59
+ ##
60
+ # Minimal preset (bold, italic, link).
61
+ # @return [Array<Symbol>]
62
+ PRESET_MINIMAL = %i[bold italic link].freeze
63
+
64
+ ##
65
+ # Standard preset with common formatting options.
66
+ # @return [Array<Symbol>]
67
+ PRESET_STANDARD = (FORMATTING_BUTTONS + %i[link heading bullet_list ordered_list blockquote]).freeze
68
+
69
+ ##
70
+ # Full preset with all available buttons.
71
+ # @return [Array<Symbol>]
72
+ PRESET_FULL = (FORMATTING_BUTTONS + BLOCK_BUTTONS + INSERT_BUTTONS).freeze
73
+
74
+ ##
75
+ # Initialize a new toolbar configuration.
76
+ #
77
+ # @param style [Symbol] toolbar style (:floating, :fixed, :none)
78
+ # @param buttons [Array<Symbol>, nil] custom button list (defaults to preset)
79
+ # @param position [Symbol] toolbar position (:top, :bottom)
80
+ #
81
+ def initialize(style: :floating, buttons: nil, position: :top)
82
+ @style = style.to_sym
83
+ @buttons = buttons || default_buttons_for_style
84
+ @position = position.to_sym
85
+ end
86
+
87
+ ##
88
+ # Check if toolbar uses floating (bubble menu) style.
89
+ #
90
+ # @return [Boolean] true if floating style
91
+ #
92
+ def floating?
93
+ style == :floating
94
+ end
95
+
96
+ ##
97
+ # Check if toolbar uses fixed style.
98
+ #
99
+ # @return [Boolean] true if fixed style
100
+ #
101
+ def fixed?
102
+ style == :fixed
103
+ end
104
+
105
+ ##
106
+ # Check if toolbar is hidden.
107
+ #
108
+ # @return [Boolean] true if toolbar is hidden
109
+ #
110
+ def hidden?
111
+ style == :none
112
+ end
113
+
114
+ ##
115
+ # Generate data attributes for Stimulus controller.
116
+ #
117
+ # @return [Hash] data attributes hash
118
+ #
119
+ def data_attributes
120
+ {
121
+ "inkpen--toolbar-style-value" => style.to_s,
122
+ "inkpen--toolbar-buttons-value" => buttons.to_json,
123
+ "inkpen--toolbar-position-value" => position.to_s
124
+ }
125
+ end
126
+
127
+ private
128
+
129
+ ##
130
+ # Get default buttons based on toolbar style.
131
+ #
132
+ # @return [Array<Symbol>] default button list
133
+ #
134
+ def default_buttons_for_style
135
+ case style
136
+ when :floating
137
+ PRESET_STANDARD
138
+ when :fixed
139
+ PRESET_FULL
140
+ else
141
+ []
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Inkpen
4
+ VERSION = "0.7.1"
5
+ end
data/lib/inkpen.rb ADDED
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "inkpen/version"
4
+ require_relative "inkpen/engine"
5
+ require_relative "inkpen/configuration"
6
+ require_relative "inkpen/editor"
7
+ require_relative "inkpen/toolbar"
8
+ require_relative "inkpen/sticky_toolbar"
9
+ require_relative "inkpen/markdown_mode"
10
+
11
+ # Extensions
12
+ require_relative "inkpen/extensions/base"
13
+ require_relative "inkpen/extensions/forced_document"
14
+ require_relative "inkpen/extensions/mention"
15
+ require_relative "inkpen/extensions/code_block_syntax"
16
+ require_relative "inkpen/extensions/table"
17
+ require_relative "inkpen/extensions/task_list"
18
+ require_relative "inkpen/extensions/slash_commands"
19
+ require_relative "inkpen/extensions/section"
20
+ require_relative "inkpen/extensions/preformatted"
21
+
22
+ ##
23
+ # Inkpen is a TipTap-based rich text editor gem for Rails applications.
24
+ #
25
+ # It provides a customizable WYSIWYG editor with Notion-like features including:
26
+ # - Block-based editing with drag & drop
27
+ # - Slash commands for quick block insertion
28
+ # - Multiple toolbar options (floating, fixed, sticky)
29
+ # - 16+ custom TipTap extensions
30
+ # - Export to Markdown, HTML, and PDF
31
+ #
32
+ # @example Basic usage with Rails form
33
+ # <%= inkpen_editor form, :content %>
34
+ #
35
+ # @example With configuration
36
+ # Inkpen.configure do |config|
37
+ # config.toolbar = :floating
38
+ # config.extensions = [:bold, :italic, :link, :slash_commands]
39
+ # config.placeholder = "Start writing..."
40
+ # end
41
+ #
42
+ # @example Full-featured editor
43
+ # <%= inkpen_editor form, :content,
44
+ # toolbar: :sticky,
45
+ # extensions: [:slash_commands, :block_gutter, :drag_handle, :export_commands] %>
46
+ #
47
+ # @see Inkpen::Configuration Global configuration options
48
+ # @see Inkpen::Editor Editor instance configuration
49
+ # @see Inkpen::Extensions Extension system
50
+ #
51
+ # @author Nauman Tariq
52
+ # @since 0.1.0
53
+ #
54
+ module Inkpen
55
+ ##
56
+ # Base error class for all Inkpen errors.
57
+ #
58
+ class Error < StandardError; end
59
+
60
+ class << self
61
+ ##
62
+ # @return [Configuration] the global configuration instance
63
+ attr_writer :configuration
64
+
65
+ ##
66
+ # Returns the global configuration instance.
67
+ #
68
+ # @return [Configuration] the configuration object
69
+ #
70
+ def configuration
71
+ @configuration ||= Configuration.new
72
+ end
73
+
74
+ ##
75
+ # Configure Inkpen globally.
76
+ #
77
+ # @yield [config] Yields the configuration object for modification
78
+ # @yieldparam config [Configuration] the configuration object
79
+ #
80
+ # @example
81
+ # Inkpen.configure do |config|
82
+ # config.toolbar = :floating
83
+ # config.extensions = [:bold, :italic, :link]
84
+ # end
85
+ #
86
+ def configure
87
+ yield(configuration)
88
+ end
89
+
90
+ ##
91
+ # Reset configuration to defaults.
92
+ #
93
+ # Useful for testing or reinitializing the editor configuration.
94
+ #
95
+ # @return [Configuration] the new configuration object
96
+ #
97
+ def reset_configuration!
98
+ @configuration = Configuration.new
99
+ end
100
+ end
101
+ end
data/sig/inkpen.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Inkpen
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end