Skip to content

Commit e7ed9b9

Browse files
committed
Initial commit.
0 parents  commit e7ed9b9

16 files changed

+495
-0
lines changed

.editorconfig

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; Indicate this is the root of the project.
2+
root = true
3+
4+
[*]
5+
indent_size = 2
6+
indent_style = space
7+
insert_final_newline = true
8+
trim_trailing_whitespace = true
9+
10+
[*.{html,js,md,rb}]
11+
charset = utf-8
12+
13+
[*.{md,txt}]
14+
max_line_length = 80

.gitignore

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Backup files
2+
*.skb
3+
AutoSave_*.skp
4+
Backup of *.layout
5+
6+
# Archives
7+
*.rbz
8+
9+
# RuboCop
10+
.rubocop-https-*-yml
11+
12+
# YARD
13+
/.yardoc
14+
/doc
15+
16+
# SimpleCov
17+
/coverage
18+
19+
# Bundler
20+
Gemfile.lock
21+
22+
/assets

.rubocop.yml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
require: rubocop-sketchup
2+
3+
# If you want to use the same codding pattern as SketchUp's projects, enable
4+
# the next line. RuboCop will then use the coding pattern from the
5+
# rubocop-sketchup project. This coding pattern is a more relaxed version than
6+
# the default RuboCop pattern.
7+
# inherit_from: https://raw.githubusercontent.com/SketchUp/rubocop-sketchup/main/sketchup-style.yml
8+
9+
AllCops:
10+
# This prevents normal RuboCop cops to run. Disable this to get full static
11+
# analysis of your Ruby code.
12+
DisabledByDefault: true
13+
14+
DisplayCopNames: true
15+
DisplayStyleGuide: true
16+
ExtraDetails: true
17+
Exclude:
18+
- src/*/vendor/**/* # Exclude skippy vendor folder
19+
SketchUp:
20+
SourcePath: src
21+
TargetSketchUpVersion: 2017
22+
Exclude: # Exclude common folders.
23+
- profiling/
24+
- skippy/
25+
- tests/
26+
TargetRubyVersion: 2.2
27+
28+
29+
# If DisabledByDefault is set to true then we need to enable the SketchUp
30+
# related departments:
31+
32+
SketchupDeprecations:
33+
Enabled: true
34+
35+
SketchupPerformance:
36+
Enabled: true
37+
38+
SketchupRequirements:
39+
Enabled: true
40+
41+
SketchupSuggestions:
42+
Enabled: true
43+
44+
SketchupBugs:
45+
Enabled: true
46+
47+
48+
# This generator makes some assumptions about the model structure.
49+
SketchupSuggestions/ModelEntities:
50+
Enabled: false
51+
52+
# This is a Trimble project, so we can use the Trimble namespace.
53+
SketchupRequirements/ShippedExtensionsNamespace:
54+
Enabled: false

.solargraph.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require_paths:
2+
- "C:/Program Files/SketchUp/SketchUp 2022/Tools"
3+
- src
4+
5+
require:
6+
- sketchup-api-stubs
7+
8+
reporters:
9+
- rubocop

.vscode/extensions.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3+
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4+
// List of extensions which should be recommended for users of this workspace.
5+
"recommendations": [
6+
// Spell checking code and comments are important.
7+
"streetsidesoftware.code-spell-checker",
8+
9+
// Will make VSCode pick up .editorconfig.
10+
"editorconfig.editorconfig",
11+
12+
// Essential for Ruby syntax highlighting and debugging.
13+
"rebornix.ruby",
14+
15+
// For code insight and auto-complete.
16+
"castwide.solargraph"
17+
],
18+
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
19+
"unwantedRecommendations": []
20+
}

.vscode/launch.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
8+
{
9+
"name": "Listen for rdebug-ide",
10+
"type": "Ruby",
11+
"request": "attach",
12+
"cwd": "${workspaceRoot}",
13+
"remoteHost": "127.0.0.1",
14+
"remotePort": "7000",
15+
"remoteWorkspaceRoot": "${workspaceRoot}"
16+
}
17+
]
18+
}

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"solargraph.diagnostics": true,
3+
}

.vscode/tasks.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
// See https://go.microsoft.com/fwlink/?LinkId=733558
3+
// for the documentation about the tasks.json format
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"label": "Launch SketchUp in Ruby debug mode",
8+
"type": "shell",
9+
"command": "skippy",
10+
"args": [
11+
"sketchup:debug",
12+
"${input:sketchupVersion}"
13+
],
14+
"runOptions": {
15+
"reevaluateOnRerun": false
16+
},
17+
"problemMatcher": []
18+
}
19+
],
20+
"inputs": [
21+
{
22+
"id": "sketchupVersion",
23+
"type": "pickString",
24+
"description": "SketchUp Version",
25+
"options": [
26+
"2021",
27+
"2020",
28+
"2019",
29+
"2018",
30+
"2017"
31+
],
32+
"default": "2021"
33+
}
34+
]
35+
}

.yardopts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
--private
2+
--markup markdown
3+
--markup-provider commonmarker
4+
src/**/*.rb
5+
-
6+
README.md

Gemfile

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
source 'https://rubygems.org'
2+
3+
group :development do
4+
gem 'debase', '~> 0.2' # VSCode debugging
5+
gem 'ruby-debug-ide', '~> 0.7' # VSCode debugging
6+
gem 'sketchup-api-stubs' # VSCode SketchUp API insight
7+
gem 'skippy', '~> 0.5.1.a'
8+
gem 'solargraph' # VSCode IDE support
9+
end
10+
11+
group :documentation do
12+
gem 'commonmarker', '~> 0.23'
13+
gem 'yard', '~> 0.9'
14+
end
15+
16+
group :analysis do
17+
gem 'rubocop', '>= 1.30', '< 2.0'
18+
gem 'rubocop-sketchup', '~> 1.3.0'
19+
end

LICENSE.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2017-2022 Trimble Inc, SketchUp Team
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

src/su_interactive_api_docs.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'extensions.rb'
2+
3+
module Trimble
4+
module InteractiveSketchUpRubyAPI
5+
6+
extension = SketchupExtension.new("API Extension", "su_interactive_api_docs/main")
7+
extension.name = "Interactive API Documentation"
8+
extension.description = "Interactive SketchUp Ruby API documentation."
9+
extension.version = "1.0.0"
10+
extension.copyright = "2017-2022"
11+
extension.creator = "Trimble Inc"
12+
Sketchup.register_extension(extension, true)
13+
14+
end
15+
end

src/su_interactive_api_docs/dialog.rb

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
module Trimble
2+
module InteractiveSketchUpRubyAPI
3+
4+
module DocumentationDialog
5+
6+
path = __dir__
7+
path.force_encoding('UTF-8')
8+
PATH = path.freeze
9+
10+
#This is what gets called when the user clicks the Icon - this is where everything really starts.
11+
def self.open
12+
options = {
13+
:dialog_title => "Interactive SketchUp Ruby API documentation",
14+
:scrollable => true,
15+
:resizable => true,
16+
:width => 1100,
17+
:height => 700,
18+
:left => 100,
19+
:top => 100,
20+
}
21+
22+
@dialog_to_ruby = UI::HtmlDialog.new(options)
23+
@dialog_to_ruby.set_url("https://ruby.sketchup.com/")
24+
25+
26+
# This block gets called every time a page in the API gets loaded. This
27+
# block is what kicks off the process to re-write all the sample
28+
# snippets as code editors.
29+
# What it does is first injects some special css styles into the page.
30+
@dialog_to_ruby.add_action_callback("page_loaded") { |action_context|
31+
inject_css(@dialog_to_ruby)
32+
inject_ace(@dialog_to_ruby)
33+
}
34+
35+
# This gets called once the html is modified with the new css, the new
36+
# Ace editor code is injected and accepted. I had tried combining this
37+
# functionality with the inject_ace method. However when I tried to load
38+
# the ace.js script at the same time as running this script, it would
39+
# not work. I think there was a race condition and this script would not
40+
# find the ace editor js code. So that is why this has to be called
41+
# completely separately, after ace is completely loaded.
42+
@dialog_to_ruby.add_action_callback("inject_ace_editors") { |action_context|
43+
ace_loader_path = File.join(PATH, "resources", "aceloader.js")
44+
ace_loader_string = IO.read(ace_loader_path)
45+
@dialog_to_ruby.execute_script(ace_loader_string)
46+
}
47+
48+
49+
# This is what gets called by the editor when the user clicks the
50+
# "Execute in Sketchup" button. That button sends the string from the
51+
# editor to this block, which then evals the string in SketchUp.
52+
@dialog_to_ruby.add_action_callback("htmlDialog_to_ruby") { |action_context, code|
53+
SKETCHUP_CONSOLE.show
54+
result = eval(code)
55+
p result
56+
}
57+
58+
@dialog_to_ruby.show
59+
end
60+
61+
# Inject css to the head of the page to stylize the editor divs. This has
62+
# to happen before we attempt to inject the code editors because they
63+
# rely on this css.
64+
def self.inject_css(dialog)
65+
ace_css_path = File.join(PATH, "resources", "ace.css")
66+
ace_css_string = IO.read(ace_css_path)
67+
ace_css_string.delete!("\n")
68+
69+
# This takes the nicely formatted css string and creates the appropriate
70+
# style element in the html page. Then injects the css into the page so
71+
# that the editors have some special css that they need.
72+
dialog.execute_script(%Q~
73+
var thehead = document.head;
74+
var style_wrap = document.createElement('style');
75+
style_wrap.innerHTML="#{ace_css_string}";
76+
thehead.appendChild(style_wrap);
77+
~)
78+
end
79+
80+
# This injects a script element into the page. It works like this: Once
81+
# the page is done loading, this script executes the callback defined in
82+
# this file called sketchup.inject_ace_editors. Read the comments on that
83+
# callback block to understand how the code editor swap works.
84+
# Another point to note. Ideally we could have just put this small js
85+
# script on every page, and removed the initial page_loaded callback. But
86+
# that would work to replace the code editors on the first page that loads
87+
# but it would not work on subsequent pages. So that is why I've added
88+
# a callback that tells the extension that a pages has loaded, then the
89+
# extension is aware of every time a new page loads, and the extension
90+
# starts the process of injecting css and js onto the page and swapping in
91+
# the code editors.
92+
def self.inject_ace(dialog)
93+
# The "A" parameter is a red herring. It does nothing. There is/was a
94+
# bug that required that I pass in something/anything. So I pass in the
95+
# A, but it is not used, nor does it mean anything.
96+
dialog.execute_script(%Q~
97+
var script = "https://cdn.jsdelivr.net/ace/1.2.3/min/ace.js";
98+
var el = document.createElement('script');
99+
var body = document.getElementsByTagName("body")[0]
100+
body.appendChild(el);
101+
el.onload = function() {
102+
sketchup.inject_ace_editors("A");
103+
};
104+
el.src = script;
105+
~)
106+
end
107+
108+
end
109+
end
110+
end
111+
112+

src/su_interactive_api_docs/main.rb

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require "sketchup.rb"
2+
3+
require "su_interactive_api_docs/dialog"
4+
5+
module Trimble
6+
module InteractiveSketchUpRubyAPI
7+
8+
unless file_loaded?(__FILE__)
9+
10+
# Commands
11+
cmd = UI::Command.new("Interactive SketchUp Ruby API documentation") {
12+
DocumentationDialog.open
13+
}
14+
cmd.tooltip = "Open the Interactive Ruby API documentation dialog."
15+
cmd_interactive_documentation = cmd
16+
17+
# Menus
18+
menu_name = Sketchup.version.to_f < 21.1 ? 'Plugins' : 'Developer'
19+
menu = UI.menu(menu_name)
20+
menu.add_item(cmd_interactive_documentation)
21+
22+
# Toolbars
23+
toolbar = UI::Toolbar.new("Ruby API Documentation")
24+
toolbar.add_item(cmd_interactive_documentation)
25+
26+
file_loaded(__FILE__)
27+
end
28+
29+
end
30+
end

0 commit comments

Comments
 (0)