├── .gitignore ├── BERT ├── .gitignore ├── BERT.sln └── BERT │ ├── BERT.rc │ ├── BERT.vcxproj │ ├── BERT.vcxproj.filters │ ├── include │ ├── basic_functions.h │ ├── bert.h │ ├── bert_graphics.h │ ├── bert_version.h │ ├── callback_info.h │ ├── com_object_map.h │ ├── debug_functions.h │ ├── excel_api_functions.h │ ├── excel_com_type_libraries.h │ ├── file_change_watcher.h │ ├── function_descriptor.h │ ├── language_desc.h │ ├── language_service.h │ ├── stdafx.h │ ├── targetver.h │ └── type_conversions.h │ ├── resource.h │ └── src │ ├── basic_functions.cc │ ├── bert.cc │ ├── bert.def │ ├── bert_graphics.cc │ ├── com_object_map.cc │ ├── debug_functions.cc │ ├── dllmain.cpp │ ├── excel_api_functions.cc │ ├── file_change_watcher.cc │ ├── language_desc.cc │ └── language_service.cc ├── Build ├── .gitignore ├── README.md ├── Welcome.md ├── bert-config-template.json ├── bert-languages.json ├── startup │ ├── startup-0.6.jl │ ├── startup-0.7.jl │ └── startup.R └── user-stylesheet-template.less ├── Common ├── json11 │ ├── json11.cpp │ └── json11.hpp ├── message_utilities.cc ├── message_utilities.h ├── module_functions.cc ├── module_functions.h ├── pipe.cc ├── pipe.h ├── process_exit_codes.h ├── string_utilities.h ├── user_button.h ├── windows_api_functions.cc └── windows_api_functions.h ├── Console ├── .gitignore ├── bert2.ico ├── data │ ├── constants.json │ ├── default_config.json │ ├── menus │ │ ├── application_menu.json │ │ ├── editor_tab_context_menu.json │ │ └── terminal_context_menu.json │ ├── schemas │ │ ├── config.schema.json │ │ └── schema.schema.json │ ├── symbol_table.json │ └── themes │ │ └── test-theme.json ├── ext │ ├── cogs │ │ ├── README.md │ │ ├── cogs.css │ │ └── cogs.woff │ ├── icomoon.css │ └── icomoon.woff ├── generated │ └── variable_pb.js ├── index.html ├── less-watch-compiler.config.json ├── main.js ├── package.json ├── script │ └── generate-symbol-table.js ├── src │ ├── common │ │ ├── config_manager.ts │ │ ├── data_cache.ts │ │ ├── file_watcher.ts │ │ ├── message_utilities.ts │ │ ├── observed_proxy.ts │ │ ├── properties.ts │ │ ├── update_check.ts │ │ └── utilities.ts │ ├── editor │ │ ├── editor.ts │ │ ├── editor_document.ts │ │ ├── editor_status_bar.ts │ │ └── julia_tokenizer.ts │ ├── io │ │ ├── management_pipe.ts │ │ ├── pipe.ts │ │ └── stdio_pipe.ts │ ├── json.d.ts │ ├── renderer.ts │ ├── shell │ │ ├── annotation_addon.ts │ │ ├── cursor_client_position_addon.ts │ │ ├── custom-fit.ts │ │ ├── fontmetrics.ts │ │ ├── graphics_device.ts │ │ ├── language_interface.ts │ │ ├── language_interface_julia-0.7.ts │ │ ├── language_interface_julia.ts │ │ ├── language_interface_r.ts │ │ ├── multiplexed_terminal.ts │ │ ├── png_graphics_device.ts │ │ ├── svg_graphics_device.ts │ │ ├── terminal_implementation.ts │ │ ├── terminal_state.ts │ │ └── text_formatter.ts │ └── ui │ │ ├── alert.ts │ │ ├── dialog.ts │ │ ├── menu_utilities.ts │ │ ├── splitter.ts │ │ ├── tab_panel.ts │ │ ├── user_stylesheet.ts │ │ └── virtual_list.ts ├── style │ ├── alert.less │ ├── common.less │ ├── dialog.less │ ├── editor.less │ ├── markdown.less │ ├── splitter_window.less │ ├── style.less │ ├── tab_panel.less │ ├── terminal3.less │ ├── terminal_overlay.less │ └── virtual-list.less ├── tsconfig.json ├── typings.d.ts └── yarn.lock ├── ControlJulia-0.7 ├── .gitignore ├── ControlJulia07.vcxproj ├── ControlJulia07.vcxproj.filters ├── include │ ├── control_julia.h │ ├── io_redirector.h │ └── julia_interface.h ├── lib-0.6.2 │ ├── libjulia.def │ ├── libjulia.exp │ └── libjulia.lib ├── lib-0.7.0 │ ├── libjulia.def │ ├── libjulia.exp │ └── libjulia.lib └── src │ ├── control_julia.cc │ └── julia_interface.cc ├── ControlJulia ├── .gitignore ├── ControlJulia.vcxproj ├── ControlJulia.vcxproj.filters ├── include │ ├── control_julia.h │ └── julia_interface.h ├── lib │ ├── libjulia.def │ ├── libjulia.exp │ └── libjulia.lib └── src │ ├── control_julia.cc │ └── julia_interface.cc ├── ControlR ├── .gitignore ├── ControlR.vcxproj ├── ControlR.vcxproj.filters ├── include │ ├── console_graphics_device.h │ ├── controlr.h │ ├── controlr_common.h │ ├── convert.h │ ├── gdi_graphics_device.h │ └── spreadsheet_graphics_device.h ├── lib │ ├── R64.lib │ ├── RGraphApp64.lib │ └── RebuildLibs.ps1 └── src │ ├── console_graphics_device.cc │ ├── controlr.cc │ ├── convert.cc │ ├── gdi_graphics_device.cc │ ├── rinterface_common.cc │ ├── rinterface_win.cc │ └── spreadsheet_graphics_device.cc ├── Examples ├── excel-functions.r ├── excel-scripting.jl ├── excel-scripting.r ├── functions.jl └── functions.r ├── Install ├── .gitignore ├── README.md ├── bert2.ico ├── build-installer.ps1 ├── install-script.nsi └── license.txt ├── Module ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── R │ └── BERTModule.R ├── README.md ├── man │ ├── BERT.console.graphics.device.Rd │ ├── BERT.graphics.device.Rd │ ├── close.js.client.progress.bar.Rd │ ├── history.Rd │ ├── pad.excel.array.Rd │ ├── print.ordered.history.Rd │ └── range.to.data.frame.Rd └── src │ └── BERTModule.cc ├── OfficeTypes ├── excel-14.tlh ├── excel-15.tlh ├── excel.tlh ├── excel.tli ├── mso-14.tlh ├── mso-15.tlh ├── mso.tlh └── mso.tli ├── PB ├── build.sh ├── variable.pb.cc ├── variable.pb.h └── variable.proto ├── README.md ├── Ribbon ├── .gitignore ├── BERTRibbon2.idl ├── BERTRibbon2.rc ├── BERTRibbon2.rgs ├── BERTRibbon2.vcxproj ├── BERTRibbon2.vcxproj.filters ├── Ribbon.def ├── dllmain.cpp ├── images │ ├── console-16.png │ └── console-32.png ├── resource.h ├── ribbon.cc ├── ribbon_connect.cc ├── ribbon_connect.h ├── ribbon_ui.xml ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── bert2-logo.svg └── logo-transparent.svg /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # folders have local .gitignore files for the various relevant types. 3 | # this top-level folder is just for R module build artifacts 4 | 5 | BERTModule_*.gz 6 | notes.md 7 | 8 | yarn-error.log 9 | -------------------------------------------------------------------------------- /BERT/.gitignore: -------------------------------------------------------------------------------- 1 | BERT/ExcelLib 2 | x64 3 | BERT/x64 4 | BERT/Win32 5 | .vs 6 | 7 | *.exp 8 | *.lib 9 | *.pdb 10 | *.ilk 11 | *.iobj 12 | *.ipdb 13 | *.aps 14 | *.tmp 15 | 16 | enc_temp_folder 17 | 18 | *.vcxproj.user 19 | 20 | *.exe 21 | *.xll 22 | -------------------------------------------------------------------------------- /BERT/BERT/BERT.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/BERT/BERT/BERT.rc -------------------------------------------------------------------------------- /BERT/BERT/include/bert_graphics.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | namespace BERTGraphics { 23 | 24 | void UpdateGraphics(const BERTBuffers::GraphicsUpdate &graphics, LPDISPATCH application_dispatch); 25 | 26 | bool QuerySize(const std::string &name, BERTBuffers::CallResponse &response, LPDISPATCH application_dispatch); 27 | 28 | } -------------------------------------------------------------------------------- /BERT/BERT/include/bert_version.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #define BERT_VERSION L"2.4.3" 23 | 24 | -------------------------------------------------------------------------------- /BERT/BERT/include/callback_info.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "stdafx.h" 23 | #include "variable.pb.h" 24 | 25 | class CallbackInfo { 26 | public: 27 | HANDLE default_unsignaled_event_; 28 | HANDLE default_signaled_event_; 29 | BERTBuffers::CallResponse callback_call_; 30 | BERTBuffers::CallResponse callback_response_; 31 | 32 | public: 33 | CallbackInfo() { 34 | default_signaled_event_ = CreateEvent(0, TRUE, TRUE, 0); 35 | default_unsignaled_event_ = CreateEvent(0, TRUE, FALSE, 0); 36 | } 37 | 38 | ~CallbackInfo() { 39 | CloseHandle(default_signaled_event_); 40 | CloseHandle(default_unsignaled_event_); 41 | } 42 | 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /BERT/BERT/include/debug_functions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #ifdef _DEBUG 26 | 27 | int DebugOut(const char *fmt, ...); 28 | 29 | // thanks to 30 | // https://stackoverflow.com/questions/16703835/visual-studio-how-can-i-see-cout-output-in-a-non-console-application 31 | // 32 | // although using streams may be preferable from a development standpoint, there's a drawback 33 | // in that if we start using cout/cerr for development logging, these won't go away in release 34 | // builds. the benefit of using the old DebugOut function is that it can get completely removed 35 | // by the preprocessor. 36 | // 37 | // TODO: stream wrappers that can get scrubbed? 38 | // 39 | class dbg_stream_for_stdio : public std::stringbuf 40 | { 41 | public: 42 | dbg_stream_for_stdio(const std::string &prefix = "") {} 43 | ~dbg_stream_for_stdio() { sync(); } 44 | int sync() 45 | { 46 | ::OutputDebugStringA(str().c_str()); 47 | str(std::string()); 48 | return 0; 49 | } 50 | public: 51 | static void InitStreams(); 52 | }; 53 | 54 | #else 55 | #define DebugOut(fmt, ...){} 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /BERT/BERT/include/excel_api_functions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | /** */ 23 | void RegisterFunctions(); 24 | 25 | /** 26 | * removes registered functions. this should be called before re-registering. 27 | * 28 | * FIXME: if it's safe to call this with no registered functions, then perhaps 29 | * it should just be rolled in to the register function. 30 | */ 31 | void UnregisterFunctions(const std::string &language = ""); 32 | 33 | /** 34 | * registers the "BERT.Exec.X" and "BERT.Call.X" functions for a language 35 | */ 36 | bool ExcelRegisterLanguageCalls(const char *language_name, uint32_t language_key, bool generic = false); 37 | 38 | -------------------------------------------------------------------------------- /BERT/BERT/include/excel_com_type_libraries.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | /** 23 | * include the excel COM type library (and the MSO library, which is a dependency. 24 | * typically these are constructed on the fly using *import* statements; we prefer 25 | * to use pregenerated files for consistency. 26 | * 27 | * FIXME: use the lowest possible version for compatibility? 28 | */ 29 | 30 | #undef xlStack 31 | #undef xlPrompt 32 | #undef xlSet 33 | 34 | #include "../OfficeTypes/mso.tlh" 35 | 36 | using namespace Office; 37 | 38 | typedef void * VBEPtr; 39 | typedef void * _VBProjectPtr; 40 | 41 | #include "../OfficeTypes/excel.tlh" 42 | -------------------------------------------------------------------------------- /BERT/BERT/include/file_change_watcher.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | // the loop timeout also functions as a debounce timeout, 26 | // because we receive duplicate notifications on file changes. 27 | // we can use separate timeouts for debouncing... 28 | 29 | #define FILE_WATCH_LOOP_DEBOUNCE_TIMEOUT 150 30 | #define FILE_WATCH_LOOP_NORMAL_TIMEOUT 500 31 | 32 | #define FILE_WATCH_EVENT_MASK (FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_FILE_NAME) 33 | 34 | typedef void (*FileWatchCallback)(void*, const std::vector&); 35 | 36 | /** 37 | * utility for watching directory changes (and implicitly file changes). 38 | * we need to run this on a separate thread, and call back to BERT via 39 | * COM to get on the correct thread. 40 | */ 41 | class FileChangeWatcher { 42 | 43 | private: 44 | std::vector < std::string > watched_directories_; 45 | HANDLE update_watch_list_handle_; 46 | CRITICAL_SECTION critical_section_; 47 | 48 | void *callback_argument_; 49 | FileWatchCallback callback_function_; 50 | 51 | private: 52 | 53 | /** thread start routine */ 54 | static uint32_t __stdcall StartThread(void *data); 55 | 56 | void NotifyDirectoryChanges(const std::vector &directory_list, FILETIME update_time); 57 | 58 | /** instance thread routine */ 59 | uint32_t InstanceStartThread(); 60 | 61 | /** control flag */ 62 | bool running_; 63 | 64 | public: 65 | FileChangeWatcher(FileWatchCallback callback = 0, void *argument = 0); 66 | ~FileChangeWatcher(); 67 | 68 | public: 69 | /** add a directory to the watch list */ 70 | void WatchDirectory(const std::string &directory); 71 | 72 | /** remove a watched directory */ 73 | void UnwatchDirectory(const std::string &directory); 74 | 75 | /** start watch thread */ 76 | void StartWatch(); 77 | 78 | /** clean up */ 79 | void Shutdown(); 80 | 81 | }; 82 | -------------------------------------------------------------------------------- /BERT/BERT/include/language_desc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | #include "json11/json11.hpp" 26 | 27 | /** moving to config, struct for now */ 28 | class LanguageDescriptor { 29 | public: 30 | std::string name_; 31 | std::string executable_; 32 | std::string prefix_; 33 | std::string tag_; 34 | std::vector extensions_; 35 | std::string command_arguments_; 36 | std::string prepend_path_; 37 | uint32_t startup_resource_; 38 | std::string startup_resource_path_; 39 | std::string home_; 40 | 41 | std::vector < std::string > home_candidates_; 42 | 43 | bool named_arguments_; 44 | int32_t priority_; 45 | 46 | public: 47 | LanguageDescriptor( 48 | const std::string &name, 49 | const std::string &executable, 50 | const std::string &prefix, 51 | const std::vector &extensions, 52 | const std::string &command_arguments, 53 | const std::string &prepend_path, 54 | const std::string &home, 55 | uint32_t startup_resource, 56 | const std::string &startup_resource_path = "", 57 | const bool named_arguments = false 58 | ) 59 | : name_(name) 60 | , executable_(executable) 61 | , prefix_(prefix) 62 | , extensions_(extensions) 63 | , command_arguments_(command_arguments) 64 | , prepend_path_(prepend_path) 65 | , home_(home) 66 | , startup_resource_(startup_resource) 67 | , startup_resource_path_(startup_resource_path) 68 | , named_arguments_(named_arguments) 69 | {} 70 | 71 | LanguageDescriptor() : priority_(0), named_arguments_(false) {} 72 | 73 | LanguageDescriptor(const LanguageDescriptor &rhs) 74 | : name_(rhs.name_) 75 | , executable_(rhs.executable_) 76 | , prefix_(rhs.prefix_) 77 | , priority_(rhs.priority_) 78 | , tag_(rhs.tag_) 79 | , extensions_(rhs.extensions_) 80 | , command_arguments_(rhs.command_arguments_) 81 | , prepend_path_(rhs.prepend_path_) 82 | , home_(rhs.home_) 83 | , startup_resource_(rhs.startup_resource_) 84 | , startup_resource_path_(rhs.startup_resource_path_) 85 | , named_arguments_(rhs.named_arguments_) 86 | , home_candidates_(rhs.home_candidates_) 87 | {} 88 | 89 | public: 90 | 91 | /** 92 | * copies values from passed JSON object to language descriptor. 93 | * this is designed to support overlay from version, so that 94 | * we can overlay as much or as little data as necessary/useful. 95 | */ 96 | void FromJSON(const json11::Json& json, const std::string &home_directory); 97 | 98 | }; 99 | 100 | -------------------------------------------------------------------------------- /BERT/BERT/include/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/BERT/BERT/include/stdafx.h -------------------------------------------------------------------------------- /BERT/BERT/include/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/BERT/BERT/include/targetver.h -------------------------------------------------------------------------------- /BERT/BERT/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by BERT.rc 4 | // 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NEXT_RESOURCE_VALUE 105 11 | #define _APS_NEXT_COMMAND_VALUE 40001 12 | #define _APS_NEXT_CONTROL_VALUE 1001 13 | #define _APS_NEXT_SYMED_VALUE 101 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /BERT/BERT/src/debug_functions.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "stdafx.h" 21 | 22 | #ifdef _DEBUG 23 | 24 | int DebugOut(const char *fmt, ...) 25 | { 26 | static char msg[1024 * 32]; // ?? 27 | int ret; 28 | va_list args; 29 | va_start(args, fmt); 30 | ret = vsprintf_s(msg, fmt, args); 31 | OutputDebugStringA(msg); 32 | va_end(args); 33 | return ret; 34 | } 35 | 36 | dbg_stream_for_stdio g_DebugStreamFor_cout; 37 | dbg_stream_for_stdio g_DebugStreamFor_cerr; 38 | 39 | void dbg_stream_for_stdio::InitStreams() { 40 | std::cout.rdbuf(&g_DebugStreamFor_cout); 41 | std::cerr.rdbuf(&g_DebugStreamFor_cerr); 42 | } 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /BERT/BERT/src/dllmain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/BERT/BERT/src/dllmain.cpp -------------------------------------------------------------------------------- /BERT/BERT/src/language_desc.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "stdafx.h" 21 | #include "language_desc.h" 22 | 23 | void LanguageDescriptor::FromJSON(const json11::Json& item, const std::string &home_directory) { 24 | 25 | if (item["extensions"].is_array()) { 26 | std::vector extensions; 27 | for (const auto &extension : item["extensions"].array_items()) { 28 | extensions.push_back(extension.string_value()); 29 | } 30 | extensions_ = extensions; 31 | } 32 | 33 | if (!item["startup_resource"].is_null()) { 34 | std::string startup_resource_path = home_directory; 35 | startup_resource_path.append("startup\\"); 36 | startup_resource_path.append(item["startup_resource"].string_value()); 37 | startup_resource_path_ = startup_resource_path; 38 | } 39 | 40 | // can probably just call bool_value() regardless, should return false if not present 41 | if (!item["named_arguments"].is_null()) named_arguments_ = item["named_arguments"].bool_value(); 42 | 43 | if (!item["name"].is_null()) name_ = item["name"].string_value(); 44 | if (!item["executable"].is_null()) executable_ = item["executable"].string_value(); 45 | if (!item["prefix"].is_null()) prefix_ = item["prefix"].string_value(); 46 | 47 | if (!item["priority"].is_null()) priority_ = item["priority"].int_value(); 48 | if (!item["tag"].is_null()) tag_ = item["tag"].string_value(); 49 | 50 | if (!item["command_arguments"].is_null()) command_arguments_ = item["command_arguments"].string_value(); 51 | if (!item["prepend_path"].is_null()) prepend_path_ = item["prepend_path"].string_value(); 52 | 53 | if (item["home"].is_array()) { 54 | for (auto candidate : item["home"].array_items()) { 55 | if(candidate.is_string()) home_candidates_.push_back(candidate.string_value()); 56 | } 57 | } 58 | else if (!item["home"].is_null()) home_ = item["home"].string_value(); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Build/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | console 3 | module 4 | lib 5 | 6 | *.exp 7 | *.exe 8 | *.xll 9 | *.dll 10 | *.ilk 11 | *.pdb 12 | *.lib 13 | *.tmp 14 | *.iobj 15 | *.ipdb 16 | 17 | bert-config.json 18 | user-stylesheet.less 19 | 20 | 21 | -------------------------------------------------------------------------------- /Build/README.md: -------------------------------------------------------------------------------- 1 | 2 | Build is a target directory for various build processes, to consolidate 3 | output from different projects/build tools. 4 | 5 | This will act as the home directory for dev builds, so it needs to include 6 | any necessary support files as well. 7 | 8 | -------------------------------------------------------------------------------- /Build/Welcome.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Welcome to the BERT console! # 4 | 5 | The console has an editor for writing functions (this side), and an R shell 6 | for testing code. You can also control Excel directly from R in the shell; 7 | see `excel-scripting.R` (in your Documents folder, under BERT2) for 8 | an example. 9 | 10 | When it starts, BERT loads functions from the functions directory, 11 | Documents\BERT2. You should see some example functions installed in Excel 12 | called `R.TestAdd` and `R.EigenValues`. 13 | 14 | You can also use BERT with the statistics language Julia. See 15 | [this page][3] for more information. 16 | 17 | Have suggestions, feedback, questions, comments? Let us know! 18 | 19 | Cheers, 20 | 21 | -- [The BERT team][4] 22 | 23 | [1]: https://cran.r-project.org/ 24 | [2]: https://julialang.org/downloads/ 25 | [3]: https://bert-toolkit.com/using-julia-with-bert 26 | [4]: https://bert-toolkit.com/contact 27 | 28 | # Upgrading from BERT v1? # 29 | 30 | If you are upgrading from an older version of BERT, [check our website][5] for 31 | some additional information. 32 | 33 | [5]: https://bert-toolkit.com/whats-new#upgrading-from-bert-1 34 | 35 | # Release Notes # 36 | 37 | 2.4.0 -- Update for R 3.5.0 and support Julia 0.6.3. 38 | 39 | 2.3.0 -- Add support for Julia 0.7. [See our website for details][11]. 40 | Add versioning info to R, Julia. Support horizontal scrolling in R. 41 | 42 | 2.2.1 -- Fix for Windows 7 x64 43 | 44 | 2.2.0 -- Update for R 3.4.4 45 | 46 | Updates R to 3.4.4. Minor updates and bug fixes. 47 | 48 | 2.1.0 -- First Release of BERT 2 (15 March 2018) 49 | 50 | Version 2 represents a complete rewrite and rearchitecting of BERT. In 51 | particular, language services are moved out of process. This allows us to 52 | support multiple languages at once, as well as support killing and restarting 53 | language services. We can also connect 32-bit Excel to 64-bit R. 54 | 55 | Version 2 includes support for R and Julia. In keeping with earlier BERT 56 | releases, we include R in the default install, but you will need to install 57 | Julia separately to use it. 58 | 59 | [11]: https://bert-toolkit.com/using-julia-with-bert#julia-07 60 | 61 | # Credits # 62 | 63 | The BERT console is built using [Electron][20], [Monaco][21] and 64 | [xtermjs][22]. 65 | 66 | [20]: https://electronjs.org/ 67 | [21]: https://github.com/Microsoft/monaco-editor 68 | [22]: https://xtermjs.org/ 69 | -------------------------------------------------------------------------------- /Build/bert-config-template.json: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | * BERT configuration options. see the various sections for 4 | * more information. comments are allowed, but other than that 5 | * make sure that the file is valid json. also make sure to 6 | * escape backslashes in windows paths. 7 | */ 8 | 9 | /** 10 | * basic BERT configuration. paths in this section can use 11 | * environment variables (e.g. %userprofile% for your home 12 | * directory). 13 | * 14 | * NOTE that (for now), changes to this section will not 15 | * be reloaded. you will need to restart Excel for changes 16 | * to take effect. 17 | */ 18 | "BERT": { 19 | 20 | // per-language configuration. to enable a language, uncomment 21 | // the language section and (optionally) set the home directory. 22 | // to disable a language, delete or comment out the block. 23 | 24 | "R": { 25 | "lib": "%bert_home%\\lib" 26 | }, 27 | 28 | "Julia": { 29 | }, 30 | 31 | // files in this directory will be loaded at startup and reloaded 32 | // when changed. the same directory is used for all languages. 33 | 34 | "functionsDirectory": "%userprofile%\\Documents\\BERT2\\functions" 35 | 36 | }, 37 | 38 | /** 39 | * common shell configuration options. these (mostly) come from 40 | * xtermjs, so see that project for more detail. 41 | */ 42 | "shell": { 43 | 44 | "theme": { 45 | "background": "#fff", 46 | "foreground": "#000", 47 | "cursor": "#000" 48 | }, 49 | 50 | "fontFamily": "consolas", 51 | 52 | // we like cursor blinking, but (atm) there are some xtermjs 53 | // issues that cause hyper-blinking. we'll look into that. 54 | // you can disable. 55 | 56 | "cursorBlink": true 57 | 58 | }, 59 | 60 | /** 61 | * editor configuration options. these (mostly) come from the monaco 62 | * editor, so see that project for more detail. 63 | */ 64 | "editor": { 65 | 66 | // tip: download fira code and use programming ligatures! 67 | // https://github.com/tonsky/FiraCode 68 | 69 | /* 70 | "fontFamily": "Fira Code", 71 | "fontSize": "13px", 72 | "fontLigatures": true, 73 | */ 74 | 75 | "theme": "vs", 76 | 77 | "minimap": { 78 | "enabled": false 79 | }, 80 | 81 | // note this setting was moved from per-language configuration 82 | // to global (applies to all languages). at the moment we don't 83 | // support per-language configuration in the editor. 84 | 85 | "tabSize": 2, 86 | "insertSpaces": true 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Build/bert-languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "R", 4 | "executable": "controlR.exe", 5 | "prefix": "R", 6 | "extensions": ["r", "rsrc", "rscript"], 7 | "command_arguments": "-r \"$HOME\"", 8 | "prepend_path": "$HOME\\bin\\x64", 9 | "startup_resource": "startup.r", 10 | "named_arguments": true, 11 | "home": "%BERT_HOME%\\R-3.5.0" 12 | }, 13 | { 14 | "name": "Julia", 15 | "prefix": "Jl", 16 | "extensions": ["jl", "julia"], 17 | "command_arguments": "", 18 | "prepend_path": "$HOME\\bin", 19 | "named_arguments": false, 20 | "versions": [ 21 | { 22 | "tag": "0.7", 23 | "executable": "controlJulia07.exe", 24 | "startup_resource": "startup-0.7.jl", 25 | "home": "%localappdata%\\Julia-0.7.0-DEV", 26 | "priority": 2 27 | }, 28 | { 29 | "tag": "0.6", 30 | "executable": "controlJulia.exe", 31 | "prepend_path": "$HOME\\bin", 32 | "startup_resource": "startup-0.6.jl", 33 | "home": [ 34 | "%localappdata%\\Julia-0.6.2", 35 | "%localappdata%\\Julia-0.6.3", 36 | "%localappdata%\\Julia-0.6.4" 37 | ], 38 | "priority": 1 39 | } 40 | ] 41 | } 42 | ] 43 | -------------------------------------------------------------------------------- /Build/user-stylesheet-template.less: -------------------------------------------------------------------------------- 1 | 2 | // edit styles in this file. for most things -- fonts and colors 3 | // in the editor and in the shells -- you should use the Preferences 4 | // file. this file is for changing structural elements of the console. 5 | 6 | // for example, to swap the order of editor/shell: 7 | 8 | /* 9 | #editor { order: 3; } 10 | #terminals { order: 1; } 11 | */ 12 | 13 | // this style is interpreted as `less`; see http://lesscss.org/ 14 | 15 | -------------------------------------------------------------------------------- /Common/message_utilities.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "message_utilities.h" 21 | 22 | namespace MessageUtilities { 23 | 24 | TypeFlags CheckArrayType(const BERTBuffers::Array &arr, bool allow_nil, bool allow_missing) { 25 | TypeFlags result = (TypeFlags::integer | TypeFlags::real | TypeFlags::numeric | TypeFlags::string | TypeFlags::logical); 26 | int length = arr.data_size(); 27 | for (int i = 0; result && i < length; i++) { 28 | const auto &element = arr.data(i); 29 | switch (element.value_case()) { 30 | case BERTBuffers::Variable::ValueCase::kStr: 31 | result = result & (TypeFlags::string); 32 | break; 33 | case BERTBuffers::Variable::ValueCase::kInteger: 34 | result = result & (TypeFlags::integer | TypeFlags::numeric); 35 | break; 36 | case BERTBuffers::Variable::ValueCase::kReal: 37 | result = result & (TypeFlags::real | TypeFlags::numeric); 38 | break; 39 | case BERTBuffers::Variable::ValueCase::kBoolean: 40 | result = result & (TypeFlags::logical); 41 | break; 42 | case BERTBuffers::Variable::ValueCase::kMissing: 43 | if (!allow_missing) return TypeFlags::nil; 44 | break; 45 | case BERTBuffers::Variable::ValueCase::kNil: 46 | if (!allow_nil) return TypeFlags::nil; 47 | break; 48 | default: 49 | return TypeFlags::nil; 50 | } 51 | } 52 | return result; 53 | } 54 | 55 | bool Unframe(google::protobuf::Message &message, const char *data, uint32_t len) { 56 | int32_t bytes; 57 | memcpy(reinterpret_cast(&bytes), data, sizeof(int32_t)); 58 | return message.ParseFromArray(data + sizeof(int32_t), bytes); 59 | } 60 | 61 | bool Unframe(google::protobuf::Message &message, const std::string &message_buffer) { 62 | return Unframe(message, message_buffer.c_str(), (uint32_t)message_buffer.length()); 63 | } 64 | 65 | std::string Frame(const google::protobuf::Message &message) { 66 | int32_t bytes = message.ByteSize(); 67 | std::stringstream stream; 68 | stream.write(reinterpret_cast(&bytes), sizeof(int32_t)); 69 | message.SerializeToOstream(dynamic_cast(&stream)); 70 | return stream.str(); 71 | } 72 | 73 | #ifdef INCLUDE_DUMP_JSON 74 | 75 | /** debug/util function */ 76 | void DumpJSON(const google::protobuf::Message &message, const char *path ) { 77 | std::string str; 78 | google::protobuf::util::JsonOptions opts; 79 | opts.add_whitespace = true; 80 | google::protobuf::util::MessageToJsonString(message, &str, opts); 81 | if (path) { 82 | FILE *f; 83 | fopen_s(&f, path, "w"); 84 | if (f) { 85 | fwrite(str.c_str(), sizeof(char), str.length(), f); 86 | fflush(f); 87 | } 88 | fclose(f); 89 | } 90 | else std::cout << str << std::endl; 91 | } 92 | 93 | #endif 94 | 95 | } -------------------------------------------------------------------------------- /Common/message_utilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include "variable.pb.h" 26 | 27 | // #define INCLUDE_DUMP_JSON 28 | 29 | #ifdef INCLUDE_DUMP_JSON 30 | #include 31 | #endif 32 | 33 | /** 34 | * common utilities for protocol buffer messages 35 | */ 36 | 37 | namespace MessageUtilities { 38 | 39 | typedef enum { 40 | nil = 0x00, 41 | integer = 0x01, 42 | real = 0x02, 43 | numeric = 0x04, 44 | string = 0x08, 45 | logical = 0x10 46 | } 47 | TypeFlags; 48 | 49 | inline TypeFlags operator | (TypeFlags a, TypeFlags b) { 50 | return static_cast(static_cast(a) | static_cast(b)); 51 | } 52 | 53 | inline TypeFlags operator & (TypeFlags a, TypeFlags b) { 54 | return static_cast(static_cast(a) & static_cast(b)); 55 | } 56 | 57 | /** 58 | * check if an array is a single type, allowing nulls and missing values. 59 | * the "numeric" type means it's only numeric but has a mix of integers and 60 | * real/float values, so you probably want to reduce to real. 61 | */ 62 | TypeFlags CheckArrayType(const BERTBuffers::Array &arr, bool allow_nil = true, bool allow_missing = true); 63 | 64 | /** 65 | * unframe and return message 66 | */ 67 | bool Unframe(google::protobuf::Message &message, const char *data, uint32_t len); 68 | 69 | /** 70 | * unframe passed string 71 | */ 72 | bool Unframe(google::protobuf::Message &message, const std::string &message_buffer); 73 | 74 | /** 75 | * frame and return string 76 | */ 77 | std::string Frame(const google::protobuf::Message &message); 78 | 79 | #ifdef INCLUDE_DUMP_JSON 80 | 81 | /** debug/util function */ 82 | void DumpJSON(const google::protobuf::Message &message, const char *path = 0); 83 | 84 | #endif 85 | 86 | 87 | }; 88 | -------------------------------------------------------------------------------- /Common/module_functions.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "module_functions.h" 21 | 22 | extern HMODULE global_module_handle; 23 | 24 | namespace ModuleFunctions { 25 | 26 | std::string ModulePath() { 27 | 28 | char path[MAX_PATH]; 29 | GetModuleFileNameA(global_module_handle, path, sizeof(path)); 30 | PathRemoveFileSpecA(path); // deprecated, but the replacement is windows 8+ only 31 | 32 | std::string module_path(path); 33 | module_path.append("\\"); 34 | return module_path; 35 | 36 | } 37 | 38 | std::string ReadResource(LPTSTR resource_id) { 39 | 40 | HRSRC resource_handle; 41 | HGLOBAL global_handle = 0; 42 | DWORD resource_size = 0; 43 | std::string resource_text; 44 | 45 | resource_handle = FindResource(global_module_handle, resource_id, RT_RCDATA); 46 | 47 | if (resource_handle) { 48 | resource_size = SizeofResource(global_module_handle, resource_handle); 49 | global_handle = LoadResource(global_module_handle, resource_handle); 50 | } 51 | 52 | if (global_handle && resource_size > 0) { 53 | const void *data = LockResource(global_handle); 54 | if (data) resource_text.assign(reinterpret_cast(data), resource_size); 55 | } 56 | 57 | return resource_text; 58 | 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Common/module_functions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #define DEFAULT_BASE_KEY HKEY_CURRENT_USER 29 | #define DEFAULT_REGISTRY_KEY "Software\\BERT2" 30 | 31 | #define PATH_PATH_SEPARATOR ";" 32 | 33 | namespace ModuleFunctions { 34 | 35 | /** reads resource in this dll */ 36 | std::string ReadResource(LPTSTR resource_id); 37 | 38 | /** get the path of the current module (not containing process) */ 39 | std::string ModulePath(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Common/pipe.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | /** 33 | * FIXME: 34 | * 35 | * (1) consolidate pipe with controlR; they're diverging during development 36 | * (which is OK), but unify. 37 | * 38 | * (2) if this becomes cross-platform we probably have to do more packet management. 39 | * we can merge in the PB framing we are already doing (but maybe add 40 | * signifier/magic header?) 41 | */ 42 | 43 | #define DEFAULT_BUFFER_SIZE (8 * 1024) 44 | 45 | // we really only need 2 connections, except for dev/debug 46 | #define MAX_PIPE_COUNT 4 47 | 48 | class Pipe { 49 | 50 | private: 51 | HANDLE handle_; 52 | OVERLAPPED read_io_; 53 | OVERLAPPED write_io_; 54 | DWORD buffer_size_; 55 | std::string name_; 56 | 57 | /** read buffer is a single read, limited to pipe buffer size */ 58 | char *read_buffer_; 59 | 60 | /** 61 | * message buffer is for messages that exceed the read buffer size, they're 62 | * constructed over multiple reads 63 | */ 64 | std::string message_buffer_; 65 | 66 | std::deque write_stack_; 67 | 68 | bool connected_; 69 | bool reading_; 70 | bool writing_; 71 | bool error_; 72 | 73 | public: 74 | 75 | /** accessor */ 76 | bool connected() { return connected_; } 77 | 78 | /** accessor */ 79 | bool reading() { return reading_; } 80 | 81 | /** accessor */ 82 | bool writing() { return writing_; } 83 | 84 | /** accessor */ 85 | bool error() { return error_; } 86 | 87 | /** create pipe, accept connection and optionally block */ 88 | DWORD Start(std::string name, bool wait); 89 | 90 | /** we have a notification about connection, do any housekeeping */ 91 | void Connect(bool start_read = true); 92 | 93 | //DWORD BlockingRead(std::string &buf); 94 | 95 | 96 | DWORD Read(std::string &buffer, bool block = false); 97 | 98 | void PushWrite(const std::string &message); 99 | void QueueWrites(std::vector &list); 100 | 101 | /** 102 | * returns non-zero if data was written (without considering whether 103 | * more data is avaialable); returns 0 if either no write took place, 104 | * or a write was started but not completed. 105 | */ 106 | int NextWrite(); 107 | 108 | int StartRead(); 109 | 110 | void ClearError(); 111 | 112 | DWORD Reset(); 113 | 114 | std::string full_name(); 115 | 116 | /** accessor */ 117 | HANDLE wait_handle_read(); 118 | 119 | /** accessor */ 120 | HANDLE wait_handle_write(); 121 | 122 | /** accessor */ 123 | DWORD buffer_size(); 124 | 125 | /** accessor */ 126 | HANDLE pipe_handle(); 127 | 128 | public: 129 | Pipe(); 130 | ~Pipe(); 131 | 132 | }; 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Common/process_exit_codes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #ifndef __PROCESS_EXIT_CODES_H 21 | #define __PROCESS_EXIT_CODES_H 22 | 23 | #define PROCESS_ERROR_UNSUPPORTED_VERSION 100 24 | #define PROCESS_ERROR_CONFIGURATION_ERROR 101 25 | 26 | #endif // #ifndef __PROCESS_EXIT_CODES_H 27 | 28 | 29 | -------------------------------------------------------------------------------- /Common/string_utilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /** 27 | * some string utilities. these have varying semantics based on when they 28 | * were written and what they were written for. 29 | * 30 | * FIXME: normalize input/output/return semantics 31 | */ 32 | class StringUtilities { 33 | 34 | public: 35 | 36 | // 37 | // thanks to 38 | // http://stackoverflow.com/questions/874134/find-if-string-ends-with-another-string-in-c 39 | // 40 | static bool EndsWith(std::string const &fullString, std::string const &ending) { 41 | if (fullString.length() >= ending.length()) { 42 | return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); 43 | } 44 | else { 45 | return false; 46 | } 47 | } 48 | 49 | /** 50 | * icase string comparison, ignoring locale issues (this is for windows paths) 51 | */ 52 | static int ICaseCompare(const std::string &a, const std::string &b) { 53 | size_t len = a.length(); 54 | if (len != b.length()) return 1; 55 | for (size_t i = 0; i < len; i++) { 56 | if (toupper(a[i]) != toupper(b[i])) return 2; 57 | } 58 | return 0; 59 | } 60 | 61 | /** 62 | * escape backslashes. returns a new string. 63 | */ 64 | static std::string EscapeBackslashes(const std::string &str) { 65 | 66 | std::stringstream new_string; 67 | std::stringstream old_string(str); 68 | std::string part; 69 | 70 | while (std::getline(old_string, part, '\\')) 71 | { 72 | new_string << part; 73 | if (!old_string.eof()) new_string << "\\\\"; 74 | } 75 | 76 | return new_string.str(); 77 | } 78 | 79 | static std::string Trim(const std::string& str, const std::string& whitespace = " \r\n\t") 80 | { 81 | const auto strBegin = str.find_first_not_of(whitespace); 82 | if (strBegin == std::string::npos) 83 | return ""; // no content 84 | 85 | const auto strEnd = str.find_last_not_of(whitespace); 86 | const auto strRange = strEnd - strBegin + 1; 87 | 88 | return str.substr(strBegin, strRange); 89 | } 90 | 91 | static std::vector &Split(const std::string &s, char delim, int minLength, std::vector &elems, bool ftrim = false) 92 | { 93 | std::stringstream ss(s); 94 | std::string item; 95 | while (std::getline(ss, item, delim)) 96 | { 97 | if (ftrim) item = Trim(item); 98 | if (!item.empty() && item.length() >= minLength) elems.push_back(item); 99 | } 100 | return elems; 101 | } 102 | }; 103 | -------------------------------------------------------------------------------- /Common/user_button.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class UserButton { 6 | 7 | public: 8 | std::wstring label_; 9 | std::wstring language_tag_; 10 | std::wstring image_mso_; 11 | std::wstring tip_; 12 | uint32_t id_; 13 | 14 | public: 15 | UserButton( 16 | const std::wstring &label = L"", 17 | const std::wstring &language_tag = L"", 18 | const std::wstring &image_mso = L"", 19 | const std::wstring &tip = L"", 20 | const int id = 0) { 21 | 22 | label_ = label; 23 | language_tag_ = language_tag; 24 | image_mso_ = image_mso; 25 | tip_ = tip; 26 | id_ = id; 27 | 28 | } 29 | 30 | UserButton(const UserButton &rhs) 31 | : label_(rhs.label_) 32 | , language_tag_(rhs.language_tag_) 33 | , image_mso_(rhs.image_mso_) 34 | , tip_(rhs.tip_) 35 | , id_(rhs.id_) 36 | {} 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /Common/windows_api_functions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #define DEFAULT_BASE_KEY HKEY_CURRENT_USER 29 | #define DEFAULT_REGISTRY_KEY "Software\\BERT2" 30 | 31 | #define PATH_PATH_SEPARATOR ";" 32 | 33 | namespace APIFunctions { 34 | 35 | /** reads resource in this dll */ 36 | std::string ReadResource(LPTSTR resource_id); 37 | 38 | /** get the path of the current module (not containing process) */ 39 | std::string ModulePath(); 40 | 41 | typedef enum { 42 | Success = 0, 43 | FileNotFound = 1, 44 | FileReadError = 2 45 | } 46 | FileError; 47 | 48 | /** 49 | * list directory. returns a tuple of filename, last write. lists files only, 50 | * not directories. the return value is the _full_path_, including the directory. 51 | * 52 | * TODO: options? 53 | */ 54 | std::vector> ListDirectory(const std::string &directory); 55 | 56 | /** reads registry string */ 57 | bool GetRegistryString(std::string &result_value, const char *name, const char *key = 0, HKEY base_key = 0); 58 | 59 | /** reads registry dword */ 60 | bool GetRegistryDWORD(DWORD &result_value, const char *name, const char *key = 0, HKEY base_key = 0); 61 | 62 | /** gets path. we are caching before modifying */ 63 | std::string GetPath(); 64 | 65 | /** appends given string to path. returns new path. */ 66 | std::string AppendPath(const std::string &new_path); 67 | 68 | /** prepends given string to path. returns new path. */ 69 | std::string PrependPath(const std::string &new_path); 70 | 71 | /** sets path (for uncaching) */ 72 | void SetPath(const std::string &path); 73 | 74 | /** read a file and return contents */ 75 | FileError FileContents(std::string &contents, const std::string &path); 76 | 77 | }; 78 | -------------------------------------------------------------------------------- /Console/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | test 5 | -------------------------------------------------------------------------------- /Console/bert2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Console/bert2.ico -------------------------------------------------------------------------------- /Console/data/constants.json: -------------------------------------------------------------------------------- 1 | { 2 | "documentation": [ 3 | "this file contains various constant strings, intended to support", 4 | "replacement in other languages. some specific functions -- menus", 5 | "in particular -- are defined separately." 6 | ], 7 | 8 | "status": { 9 | "ready": "Ready", 10 | "line": "Line", 11 | "column": "Col", 12 | "rendered": "Rendered" 13 | }, 14 | 15 | "files": { 16 | "untitled": "Untitled", 17 | "preferences": "Preferences", 18 | "userStylesheet": "User Stylesheet", 19 | "welcome": "Welcome" 20 | }, 21 | 22 | "editorCommands": { 23 | "executeBuffer": "Execute Entire Buffer", 24 | "executeSelection": "Execute Selection" 25 | }, 26 | 27 | "shell": { 28 | "imageTypes": "# Images" 29 | }, 30 | 31 | "errors": { 32 | "openFileError": "We couldn't open the file. Please make sure the file exists and is readable." 33 | }, 34 | 35 | "dialogs": { 36 | "selectMirror": { 37 | "chooseMirrorTitle": "Choose CRAN Mirror", 38 | "selectMirror": "Select a Mirror:", 39 | "pleaseWait": "Loading mirror list, please wait...", 40 | "setRepo": "Set CRAN repo to #" 41 | }, 42 | "selectPackages": { 43 | "selectPackagesTitle": "Select Packages", 44 | "selectPackages": "Select Packages:", 45 | "pleaseWait": "Loading package list, please wait...", 46 | "pleaseWaitInstalled": "Checking installed packages, please wait...", 47 | "installed": "installed", 48 | "filter": "Filter", 49 | "singularSelected": "# Package Selected", 50 | "pluralSelected": "# Packages Selected" 51 | }, 52 | "buttons": { 53 | "cancel": "Cancel", 54 | "select": "Select", 55 | "install": "Install", 56 | "ok": "OK" 57 | } 58 | }, 59 | 60 | "updates": { 61 | "title": "Version $VERSION is available", 62 | "downloadLink": "Download Page", 63 | "suppressLink": "Don't Notify me Again" 64 | }, 65 | 66 | "preferences": { 67 | "ok": "Preferences OK", 68 | "error": "Preferences Error" 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /Console/data/default_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor": { 3 | "minimap": { 4 | "enabled": false 5 | }, 6 | "theme": "vs", 7 | "lineNumbers": true, 8 | "statusBar": true, 9 | "tabSize": 2, 10 | "insertSpaces": true, 11 | "roundedSelection": true, 12 | "scrollBeyondLastLine": false 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Console/data/menus/application_menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "main-menu": { 3 | "items": [ 4 | { 5 | "label": "File", "id": "file", 6 | "items": [ 7 | { "label": "New File", "id": "new-file", "accelerator": "Ctrl+N" }, 8 | { "label": "Open File...", "id": "open-file", "accelerator": "Ctrl+O" }, 9 | { "label": "Open Recent", "id": "open-recent", "enabled": false, "type": "submenu", "items": [] }, 10 | { "label": "Unclose Tab", "id": "unclose-tab", "enabled": false, "accelerator": "Ctrl+Shift+T" }, 11 | { "type": "separator" }, 12 | { "label": "Save", "id": "save-file", "accelerator": "Ctrl+S" }, 13 | { "label": "Save As...", "id": "save-file-as", "accelerator": "Ctrl+Shift+S" }, 14 | { "type": "separator" }, 15 | { "label": "Revert File", "id": "revert-file", "enabled": false }, 16 | { "label": "Close File", "id": "close-file", "accelerator": "Ctrl+W", "enabled": false }, 17 | { "type": "separator" }, 18 | { "label": "Close Console", "id": "close-console" } 19 | ] 20 | }, 21 | { 22 | "label": "Edit", "id": "edit", 23 | "items": [ 24 | { "label": "Cut", "id": "cut" }, 25 | { "label": "Copy", "id": "copy" }, 26 | { "label": "Paste", "id": "paste" }, 27 | { "type": "separator" }, 28 | { "label": "Find", "id": "find" }, 29 | { "label": "Replace", "id": "replace" } 30 | ] 31 | }, 32 | { 33 | "label": "View", "id": "view", 34 | "items": [ 35 | { "label": "Show Editor", "id": "show-editor", "type": "checkbox", "checked": true }, 36 | { "label": "Show Shell", "id": "show-shell", "type": "checkbox", "checked": true }, 37 | { 38 | "label": "Layout", "id": "layout", 39 | "items": [ 40 | { "label": "Left/Right", "type": "radio", "id": "layout-horizontal", "checked": true }, 41 | { "label": "Top/Bottom", "type": "radio", "id": "layout-vertical" } 42 | ] 43 | }, 44 | { "label": "Preferences", "id": "config" }, 45 | { "label": "User Stylesheet", "id": "user-stylesheet" }, 46 | { "type": "separator" }, 47 | { "label": "Reload", "accelerator": "Ctrl+R", "id": "reload" }, 48 | { "label": "Toggle Developer Tools", "accelerator": "Ctrl+Shift+I", "id": "toggle-developer-tools" } 49 | ] 50 | }, 51 | { 52 | "label": "Packages", "id": "packages", 53 | "hideIfEmpty": true 54 | }, 55 | { 56 | "label": "Help", "id": "help", 57 | "items": [ 58 | { "label": "BERT Version", "id": "version", "enabled": false }, 59 | { "type": "separator" }, 60 | { "label": "Feedback", "id": "feedback" }, 61 | { "label": "BERT Website", "id": "website" }, 62 | { "label": "Release Notes", "id": "release-notes" } 63 | ] 64 | } 65 | ] 66 | }, 67 | "r-packages": [ 68 | { "label": "R Packages", "id": "r", "enabled": false }, 69 | { "label": "Choose CRAN Mirror", "id": "r-choose-mirror" }, 70 | { "label": "Install Packages", "id": "r-install-packages" } 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /Console/data/menus/editor_tab_context_menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor-tab": { 3 | "items": [ 4 | { "label": "Close", "id": "tab.close" }, 5 | { "label": "Close Others", "id": "tab.close-others" }, 6 | { "label": "Close All", "id": "tab.close-all" }, 7 | { "type": "separator" }, 8 | { "label": "Copy Path", "id": "tab.copy-path", "condition": "path" }, 9 | { "label": "Open Directory", "id": "tab.open-directory", "condition": "path" } 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /Console/data/menus/terminal_context_menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "terminal-image": { 3 | "items": [ 4 | { "label": "Save Image As...", "id": "terminal-save-image" }, 5 | { "type": "separator" } 6 | ] 7 | }, 8 | 9 | "terminal": { 10 | "items": [ 11 | { "label": "Select All", "id": "terminal-select-all", "accelerator": "Ctrl+A" }, 12 | { "label": "Copy", "id": "terminal-copy", "accelerator": "Ctrl+Insert" }, 13 | { "label": "Paste", "id": "terminal-paste", "accelerator": "Ctrl+Shift+Insert" }, 14 | { "type": "separator" }, 15 | { "label": "Clear Shell", "id": "terminal-clear-shell", "accelerator": "Alt+F8" } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /Console/data/themes/test-theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "test", 3 | "base": "vs", 4 | "inherit": true, 5 | "rules": [ 6 | { "token": "keyword.control", "foreground": "ff998c" }, 7 | { "token": "comment", "foreground": "008800", "fontStyle": "italic" } 8 | ], 9 | "colors": { 10 | "editor.background": "#def" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Console/ext/cogs/README.md: -------------------------------------------------------------------------------- 1 | 2 | Cog icons by [Jiri Silha][1]. I found them via [Pasquale Vitiello][2]. 3 | 4 | [1]: https://dribbble.com/shots/1631956-Settings-Icons-PSD 5 | [2]: https://github.com/pasqualevitiello/Tumblr-Style-Cog-Spinners 6 | 7 | -------------------------------------------------------------------------------- /Console/ext/cogs/cogs.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face { 3 | font-family: 'cogs'; 4 | src: url('./cogs.woff') format('woff'); 5 | font-weight: normal; 6 | font-style: normal; 7 | } 8 | 9 | [class*='cog-']:before{ 10 | display: inline-block; 11 | font-family: 'cogs'; 12 | font-style: normal; 13 | font-weight: normal; 14 | line-height: 1; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale 17 | } 18 | 19 | .cog-01:before{content:'\0054';} 20 | .cog-02:before{content:'\0055';} 21 | .cog-03:before{content:'\0056';} 22 | .cog-04:before{content:'\0057';} 23 | .cog-05:before{content:'\0058';} 24 | .cog-06:before{content:'\0047';} 25 | .cog-07:before{content:'\0041';} 26 | .cog-08:before{content:'\0042';} 27 | .cog-09:before{content:'\0043';} 28 | .cog-10:before{content:'\0044';} 29 | .cog-11:before{content:'\0045';} 30 | .cog-12:before{content:'\0046';} 31 | .cog-13:before{content:'\0048';} 32 | .cog-14:before{content:'\0049';} 33 | .cog-15:before{content:'\004a';} 34 | .cog-16:before{content:'\004b';} 35 | .cog-17:before{content:'\004c';} 36 | .cog-18:before{content:'\004d';} 37 | .cog-19:before{content:'\004e';} 38 | .cog-20:before{content:'\004f';} 39 | .cog-21:before{content:'\0050';} 40 | .cog-22:before{content:'\0051';} 41 | .cog-23:before{content:'\0052';} 42 | .cog-24:before{content:'\0053';} 43 | -------------------------------------------------------------------------------- /Console/ext/cogs/cogs.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Console/ext/cogs/cogs.woff -------------------------------------------------------------------------------- /Console/ext/icomoon.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face { 3 | font-family: 'icomoon'; 4 | src: url('./icomoon.woff?axvxy8') format('woff'); 5 | font-weight: normal; 6 | font-style: normal; 7 | } 8 | -------------------------------------------------------------------------------- /Console/ext/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Console/ext/icomoon.woff -------------------------------------------------------------------------------- /Console/index.html: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | BERT Console 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | 38 |
39 | 40 | 41 |
42 |
43 | 44 |
45 | 46 | 52 | 53 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Console/less-watch-compiler.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "watchFolder": "style", 3 | "outputFolder": "build", 4 | "mainFile": "style.less", 5 | "sourceMap": true 6 | } -------------------------------------------------------------------------------- /Console/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | const url = require('url') 21 | const path = require('path'); 22 | const electron = require('electron') 23 | // Module to control application life. 24 | const app = electron.app 25 | // Module to create native browser window. 26 | const BrowserWindow = electron.BrowserWindow 27 | 28 | const WindowState = require('electron-window-state'); 29 | 30 | require('electron-reload')(path.join(__dirname,"build")); 31 | 32 | let dev_flags = 0; 33 | let pipe_list = []; 34 | let management_pipe = ""; 35 | 36 | process.env['BERT_CONSOLE_ROOT'] = __dirname; 37 | 38 | // we might have (in fact we expect to have) multiple pipes, 39 | // and we need to keep track of all of them. they're not 40 | // specifically identified, we ask the pipe what language 41 | // it uses. 42 | 43 | for( let i = 0; i< process.argv.length; i++ ){ 44 | 45 | let arg = process.argv[i]; 46 | let more = (i < (process.argv.length - 1)); 47 | 48 | if( arg === "-p" && more ){ 49 | pipe_list.push(process.argv[++i]); 50 | } 51 | else if( arg === "-m" && more ){ 52 | management_pipe = process.argv[++i]; 53 | } 54 | else if( arg === "-d" ){ 55 | dev_flags = Number(process.argv[++i]||1); 56 | process.env['BERT_DEV_FLAGS'] = dev_flags; 57 | } 58 | } 59 | 60 | if(management_pipe.length){ 61 | process.env['BERT_MANAGEMENT_PIPE'] = management_pipe; 62 | } 63 | 64 | if(pipe_list.length){ 65 | process.env['BERT_PIPE_NAME'] = pipe_list.join(";"); 66 | } 67 | 68 | // Keep a global reference of the window object, if you don't, the window will 69 | // be closed automatically when the JavaScript object is garbage collected. 70 | let mainWindow 71 | 72 | function createWindow () { 73 | 74 | let window_state = WindowState({ 75 | defaultWidth: 1200, defaultHeight: 800 76 | }); 77 | 78 | // Create the browser window. 79 | mainWindow = new BrowserWindow(window_state); 80 | 81 | window_state.manage(mainWindow); 82 | 83 | // and load the index.html of the app. 84 | mainWindow.loadURL(url.format({ 85 | pathname: path.join(__dirname, 'index.html'), 86 | protocol: 'file:', 87 | slashes: true 88 | })) 89 | 90 | if(dev_flags) mainWindow.webContents.openDevTools() 91 | 92 | // Emitted when the window is closed. 93 | mainWindow.on('closed', function () { 94 | // Dereference the window object, usually you would store windows 95 | // in an array if your app supports multi windows, this is the time 96 | // when you should delete the corresponding element. 97 | mainWindow = null 98 | }) 99 | } 100 | 101 | // This method will be called when Electron has finished 102 | // initialization and is ready to create browser windows. 103 | // Some APIs can only be used after this event occurs. 104 | app.on('ready', createWindow) 105 | 106 | // Quit when all windows are closed. 107 | app.on('window-all-closed', function () { 108 | // On OS X it is common for applications and their menu bar 109 | // to stay active until the user quits explicitly with Cmd + Q 110 | if (process.platform !== 'darwin') { 111 | app.quit() 112 | } 113 | }) 114 | 115 | app.on('activate', function () { 116 | // On OS X it's common to re-create a window in the app when the 117 | // dock icon is clicked and there are no other windows open. 118 | if (mainWindow === null) { 119 | createWindow() 120 | } 121 | }) 122 | 123 | // In this file you can include the rest of your app's specific main process 124 | // code. You can also put them in separate files and require them here. 125 | -------------------------------------------------------------------------------- /Console/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.4.3", 3 | "main": "main.js", 4 | "name": "bert2-console", 5 | "build": { 6 | "directories": { 7 | "output": "../Build/Console" 8 | }, 9 | "win": { 10 | "target": "dir" 11 | }, 12 | "files": [ 13 | "ext/**/*", 14 | "data/**/*", 15 | "build/**/*", 16 | "generated/*", 17 | "main.js", 18 | "index.html" 19 | ], 20 | "icon": "bert2.ico" 21 | }, 22 | "scripts": { 23 | "start": "electron .", 24 | "clean": "rm -fr build/*", 25 | "build": "./node_modules/.bin/less-watch-compiler --run-once && ./node_modules/.bin/tsc", 26 | "watch": "./node_modules/.bin/less-watch-compiler & ./node_modules/.bin/tsc --watch &", 27 | "package": "./node_modules/.bin/electron-builder", 28 | "repackage": "./node_modules/.bin/less-watch-compiler --run-once && ./node_modules/.bin/tsc && ./node_modules/.bin/electron-builder" 29 | }, 30 | "devDependencies": { 31 | "@types/node": "^8.9.1", 32 | "asar": "^0.14.1", 33 | "electron": "^1.8.2", 34 | "electron-builder": "^19.56.0", 35 | "less-watch-compiler": "^1.11.0", 36 | "typescript": "^2.7.2" 37 | }, 38 | "dependencies": { 39 | "@types/text-encoding": "^0.0.32", 40 | "chokidar": "^2.0.1", 41 | "electron-reload": "^1.2.2", 42 | "electron-window-state": "^4.1.1", 43 | "google-protobuf": "^3.5.0", 44 | "js-base64": "^2.4.3", 45 | "less": "^3.0.1", 46 | "markdown-it": "^8.4.0", 47 | "markdown-it-task-lists": "^2.1.0", 48 | "monaco-editor": "^0.10.1", 49 | "rxjs": "^5.5.6", 50 | "xterm": "^3.2.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Console/script/generate-symbol-table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | /** 21 | * the Julia REPL supports autotranslation of latex symbols. we want to do 22 | * the same thing. originally we were using html entities (via he), which is 23 | * a reasonable subset, but we can borrow Julia's list to get the full set. 24 | */ 25 | 26 | "use strict"; 27 | 28 | const https = require('https'); 29 | const fs = require('fs'); 30 | const path = require('path'); 31 | 32 | /** 33 | * this is a rawgit link generated from the latest commit (at time of writing). 34 | * any updates will require updating the tag. 35 | */ 36 | const source = "https://cdn.rawgit.com/JuliaLang/julia/ceca80c8ecb70c422bea9ff83483f1bceac494d7/stdlib/REPL/src/latex_symbols.jl"; 37 | 38 | let output_file = null; 39 | let force_overwrite = false; 40 | 41 | for( let i = 0; i< process.argv.length; i++ ){ 42 | if( process.argv[i] === '-o' && i < process.argv.length - 1 ){ 43 | output_file = process.argv[++i]; 44 | } 45 | else if( process.argv[i] === '-f' ) force_overwrite = true; 46 | } 47 | 48 | if( null === output_file ){ 49 | console.info( "Call with -o output file [-f]") 50 | return; 51 | } 52 | 53 | output_file = path.resolve(output_file); 54 | 55 | https.get(source, response => { 56 | response.setEncoding("utf8"); 57 | let text = ""; 58 | response.on("data", data => text += data); 59 | response.on("end", () => process_content(text)); 60 | }); 61 | 62 | let process_content = function(text){ 63 | 64 | let symbols = {}; 65 | 66 | // current assumption: symbols are on lines by themselves, as 67 | // "\\name" => "symbol" with optional comma (actually last line 68 | // has a comma as well). 69 | 70 | // if we read this as plain text, then we're going to see escaped 71 | // backslashes in the strings, so double. 72 | 73 | // we're not storing leading backslashes at all, so drop x2. 74 | 75 | let regex = /^"\\\\(.+?)"\s+=>\s+"(.+?)"/; 76 | text.split("\n").map(x => x.trim()).forEach(line => { 77 | let m = line.match(regex); 78 | if(m){ 79 | 80 | // some symbols are listed in the julia source as unicode escape 81 | // sequences (e.g. \u221A), but if we add the escaped string, then 82 | // it will itself be escaped. so we need to translate. 83 | 84 | if( /^\\/.test(m[2])) { 85 | symbols[m[1]] = String.fromCharCode(parseInt(m[2].substr(2), 16)); 86 | } 87 | else { 88 | symbols[m[1]] = m[2]; 89 | } 90 | } 91 | }); 92 | 93 | // we're adding some info. (at least for now, we know that 94 | // the chrome/node serializer will leave this at the top) 95 | 96 | let object = { 97 | metadata: { 98 | DESCRIPTION: "This is a map of latex symbols for the julia shell.", 99 | SOURCE: source, 100 | DATE: new Date().toDateString(), 101 | NOTE: "This file was generated by a tool. It may be overwritten." 102 | }, 103 | symbols 104 | } 105 | 106 | fs.access(output_file, err => { 107 | if( !err && !force_overwrite ){ 108 | console.info( "The file already exists. Not overwriting without -f flag."); 109 | return; 110 | } 111 | fs.writeFile(output_file, JSON.stringify(object, undefined, 2), "utf8", err => { 112 | if(err) console.error(err); 113 | else console.info( "Wrote OK"); 114 | }); 115 | }); 116 | 117 | } 118 | 119 | -------------------------------------------------------------------------------- /Console/src/common/config_manager.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | const Constants = require("../../data/constants.json"); 21 | const DefaultConfig = require("../../data/default_config.json"); 22 | 23 | import { FileWatcher } from './file_watcher'; 24 | 25 | // FIXME: export as static class member instead? 26 | export const ConfigSchema = require("../../data/schemas/config.schema.json"); 27 | 28 | import * as fs from 'fs'; 29 | import * as path from 'path'; 30 | import * as Rx from 'rxjs'; 31 | 32 | export enum ConfigLoadStatus { 33 | NotLoaded = 0, 34 | Loaded = 1, 35 | Error = 2 36 | } 37 | 38 | export interface ConfigState { 39 | config?:any; 40 | status:ConfigLoadStatus; 41 | } 42 | 43 | /** 44 | * no longer static, -> singleton 45 | */ 46 | class ConfigManager extends Rx.BehaviorSubject { 47 | 48 | /** */ 49 | public get config() : any { 50 | return this.getValue().config; 51 | } 52 | 53 | /** */ 54 | public get status() : ConfigLoadStatus { 55 | return this.getValue().status; 56 | } 57 | 58 | private raw_config_file_:string; 59 | 60 | private config_path_ = path.join( 61 | process.env['BERT_HOME'], "bert-config.json"); 62 | 63 | public get config_path(){ return this.config_path_; } 64 | 65 | constructor(){ 66 | 67 | super({ status:ConfigLoadStatus.NotLoaded }); 68 | 69 | // load the first time. that will generate an event clients can 70 | // subscribe to. then start watching the file, so we get subsequent 71 | // changes. 72 | 73 | this.ReadConfig().then(() => { 74 | FileWatcher.Watch(this.config_path); 75 | FileWatcher.events.filter( x => (x === this.config_path)).subscribe(x => { 76 | this.ReadConfig(); 77 | }); 78 | }); 79 | 80 | } 81 | 82 | /** 83 | * operates on a commented json file. insert should be pre-rendered 84 | * json. we can't handle arrays, just objects. 85 | */ 86 | InsertJSON(path:string, json:string){ 87 | let source = this.raw_config_file_; 88 | let components = path.split("."); 89 | 90 | 91 | 92 | } 93 | 94 | /** 95 | * utility function: strip comments, c style and c++ style. 96 | * for json w/ comments 97 | */ 98 | StripComments(text:string) : string { 99 | return text.replace( /\/\*[\s\S]+?\*\//g, "").split(/\n/).map( 100 | line => line.replace( /\/\/.*$/m, "" )).join("\n"); 101 | } 102 | 103 | /** 104 | * 105 | */ 106 | private ReadConfig() : Promise { 107 | return new Promise((resolve, reject) => { 108 | fs.readFile(this.config_path, "utf8", (err, json) => { 109 | if(!err){ 110 | this.raw_config_file_ = json; 111 | try { 112 | let config = JSON.parse(this.StripComments(json)); 113 | this.next({ config, status:ConfigLoadStatus.Loaded }); 114 | return resolve(); 115 | } 116 | catch(e){ 117 | console.error(e); 118 | } 119 | } 120 | else { 121 | console.error("err loading config file: " + err); 122 | } 123 | this.raw_config_file_ = DefaultConfig; 124 | this.next({ 125 | config:DefaultConfig, status:ConfigLoadStatus.Error 126 | }); 127 | return resolve(); 128 | }); 129 | }); 130 | } 131 | } 132 | 133 | export const ConfigManagerInstance = new ConfigManager(); 134 | -------------------------------------------------------------------------------- /Console/src/common/data_cache.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | 21 | const PREFIX = "cache_"; 22 | const VERSION = 2; 23 | const DEFAULT_EXPIRATION = (60 * 60 * 24); 24 | 25 | export class DataCache { 26 | 27 | static Store(key:string, data:any, expiration=DEFAULT_EXPIRATION){ 28 | let expireTime = (new Date().getTime() / 1000) + expiration; 29 | localStorage.setItem(PREFIX + key, JSON.stringify({ 30 | version:VERSION, expiration:expireTime, data 31 | })); 32 | } 33 | 34 | static Check(key:string) : DataCache.CacheStatus { 35 | return this.Get(key).status; 36 | } 37 | 38 | static Flush(key:string) { 39 | localStorage.removeItem(PREFIX + key); 40 | } 41 | 42 | static Get(key:string) : DataCache.CacheResult { 43 | let json = localStorage.getItem(PREFIX + key); 44 | let time = (new Date().getTime() / 1000); 45 | if(!json) return {status: DataCache.CacheStatus.NotFound}; 46 | try { 47 | let cache = JSON.parse(json) as DataCache.CacheData; 48 | let status = (time < cache.expiration) ? DataCache.CacheStatus.Valid : DataCache.CacheStatus.Expired; 49 | return {status, data:cache.data}; 50 | } 51 | catch(e){ 52 | console.error(e); 53 | return {status:DataCache.CacheStatus.Error}; 54 | } 55 | } 56 | 57 | } 58 | 59 | export namespace DataCache { 60 | 61 | export enum CacheStatus { 62 | NotFound, 63 | Expired, 64 | Valid, 65 | Error 66 | } 67 | 68 | export interface CacheResult { 69 | status:CacheStatus; 70 | data?:any; 71 | } 72 | 73 | export interface CacheData { 74 | version:number, 75 | expiration:number, 76 | data:any 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /Console/src/common/file_watcher.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import * as Rx from 'rxjs'; 21 | import * as chokidar from 'chokidar'; 22 | 23 | /** simple wrapper for chokidar, adds reference counting and an rx subject */ 24 | export class FileWatcher { 25 | 26 | private static reference_map_:{[index:string]:number} = {}; 27 | 28 | private static events_:Rx.Subject = new Rx.Subject(); 29 | 30 | public static get events() { return this.events_; } 31 | 32 | private static watcher_:any; 33 | 34 | public static IsWatching(file:string) : boolean { 35 | return !!this.reference_map_[file]; 36 | } 37 | 38 | static Watch(file:string){ 39 | if( this.reference_map_[file] ) this.reference_map_[file]++; 40 | else { 41 | this.reference_map_[file] = 1; 42 | if(!this.watcher_){ 43 | this.watcher_ = chokidar.watch(file, { 44 | persistent: true 45 | }); 46 | this.watcher_.on('change', (path, stats) => { 47 | this.events_.next(path); 48 | }); 49 | } 50 | else this.watcher_.add(file); 51 | } 52 | } 53 | 54 | static Unwatch(file:string){ 55 | if( !this.reference_map_[file] ) return; 56 | let count = --this.reference_map_[file]; 57 | if(count) return; 58 | this.reference_map_[file] = 0; 59 | delete this.reference_map_[file]; // necessary? 60 | 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /Console/src/common/observed_proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | export class ObservedProxy { 21 | 22 | static Create(object:any, callback:Function){ 23 | const BuildProxy = function(object:any, prefix:string){ 24 | return new Proxy(object, { 25 | set: function(target, property, value) { 26 | if( target[property] !== value ){ 27 | target[property] = value; 28 | callback.call(null, prefix + property.toString(), value); 29 | } 30 | return true; 31 | }, 32 | get: function(target, property) { 33 | let out = target[property]; 34 | if (out instanceof Object && typeof property === "string") { 35 | return BuildProxy(out, prefix + property + '.'); 36 | } 37 | return out; 38 | }, 39 | }); 40 | } 41 | return BuildProxy(object, ""); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Console/src/common/properties.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import * as Rx from 'rxjs'; 21 | import { ObservedProxy } from './observed_proxy'; 22 | 23 | export interface PropertyNotifcation { 24 | property: string; 25 | value: any; 26 | } 27 | 28 | /** 29 | * FIXME: like config, this class should (perhaps) inherit from 30 | * subject or behavior subject 31 | */ 32 | export class PropertyManager { 33 | 34 | /** notification */ 35 | private change_ = new Rx.Subject(); 36 | 37 | /** accessor */ 38 | public get change() { return this.change_; } 39 | 40 | /** opaque properties object */ 41 | private properties_:any; 42 | 43 | /** accessor */ 44 | public get properties(){ return this.properties_; } 45 | 46 | /** 47 | * we use a template to preset expected property structure, so that we 48 | * can assume the existence of collections/objects. the proxy doesn't 49 | * really support creating structure on the fly. 50 | */ 51 | constructor(private storage_key_:string, template:any, read_existing = true){ 52 | 53 | let base = {}; 54 | let on_change:Function; 55 | 56 | if( storage_key_ ){ 57 | if( read_existing ){ 58 | let model = localStorage.getItem(storage_key_); 59 | if( model ){ 60 | try { 61 | base = JSON.parse(model); 62 | } 63 | catch(e){ 64 | console.error( "ERROR parsing storage model: " + e ); 65 | } 66 | } 67 | } 68 | on_change = (property, value) => { 69 | this.change_.next({ property, value }); 70 | localStorage.setItem(storage_key_, JSON.stringify(this.properties_)); 71 | }; 72 | } 73 | else { 74 | on_change = (property, value) => { 75 | this.change_.next({ property, value }); 76 | }; 77 | } 78 | 79 | if(template) this.ApplyTemplate(base, template); 80 | 81 | this.properties_ = ObservedProxy.Create(base, on_change); 82 | 83 | } 84 | 85 | ApplyTemplate(base:any, template:any){ 86 | Object.keys(template).forEach( key => { 87 | if(!base.hasOwnProperty(key)){ 88 | base[key] = JSON.parse(JSON.stringify(template[key])); // dumb deep copy // actually smart, see benchmarks 89 | } 90 | else { 91 | this.ApplyTemplate(base[key], template[key]); 92 | } 93 | }); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /Console/src/common/update_check.ts: -------------------------------------------------------------------------------- 1 | 2 | import {AlertManager, AlertResult, AlertSpec} from '../ui/alert'; 3 | import {shell as electron_shell} from 'electron'; 4 | 5 | const Constants = require("../../data/constants.json"); 6 | 7 | export namespace UpdateCheck { 8 | 9 | /** 10 | * checks for updates. if the current version > this version, alerts 11 | * the user. the user can say "don't notify me about this version again", 12 | * in which case we will toll notification until the _next_ update. 13 | * 14 | * fixme: allow disable? 15 | */ 16 | export async function CheckForUpdates(prefs, alert_manager:AlertManager){ 17 | 18 | // there's a chrome bug (not a bug) that prevents setting the UA 19 | // header, but electron is helpfully adding our process name/version 20 | // anyway. 21 | 22 | // (as I recall we can set headers using old-style XHRs, if necessary) 23 | 24 | /* 25 | let headers = new Headers({ 26 | "User-Agent": "BERT-Console-" + process.env.BERT_VERSION 27 | }); 28 | */ 29 | 30 | let response = await fetch("https://bert-toolkit.com/version.json", {cache: "no-cache"}); 31 | let version_object = await response.json(); 32 | 33 | let version_number = 34 | version_object.version.split(".").reduce((a,x) => a * 1000 + Number(x), 0); 35 | 36 | let current_version = 37 | process.env.BERT_VERSION.split(".").reduce((a,x) => a * 1000 + Number(x), 0); 38 | 39 | // version is up-to-date (or newer) 40 | if( current_version >= version_number ) return; 41 | 42 | // already notified 43 | let suppress_version = prefs.console.suppress_version || 0; 44 | if( suppress_version === version_number ) return; 45 | 46 | alert_manager.Show({ 47 | escape: true, enter: true, 48 | title: Constants.updates.title.replace(/\$VERSION/, version_object.version), 49 | message: ` ` 50 | }).then(result => { 51 | switch(result.data){ 52 | case "suppress": 53 | prefs.console.suppress_version = version_number; 54 | break; 55 | case "download": 56 | electron_shell.openExternal(version_object.link); 57 | break; 58 | } 59 | }); 60 | 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /Console/src/common/utilities.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import { Base64 } from 'js-base64'; 21 | 22 | export class Utilities { 23 | 24 | /** 25 | * thanks to 26 | * https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string 27 | */ 28 | static Uint8ToBase64(data:Uint8Array):string{ 29 | 30 | let chunks = []; 31 | let block = 0x8000; 32 | for( let i = 0; i< data.length; i += block){ 33 | chunks.push( String.fromCharCode.apply(null, data.subarray(i, i + block))); 34 | } 35 | return Base64.encode(chunks.join("")); 36 | 37 | } 38 | 39 | static VersionToNumber(version_string){ 40 | return version_string.split(".").reduce((a,x) => a * 1000 + (Number(x)||0)); 41 | } 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Console/src/editor/editor_document.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | /// 21 | 22 | /** 23 | * document types with different rendering behavior 24 | */ 25 | export enum DocumentType { 26 | rendered = "rendered", 27 | editor = "editor", 28 | config = "config" 29 | } 30 | 31 | /** 32 | * class represents a document in the editor; has content, view state. 33 | * extended to support static (i.e. rendered) documents, which are 34 | * displayed as html. 35 | * 36 | * FIXME: base type, subtypes for rendered/editor documents? 37 | */ 38 | export class Document { 39 | 40 | /** label: the file name, generally, or "untitled-x" */ 41 | label_: string; 42 | 43 | /** path to file. null for "new" files that have never been saved. */ 44 | file_path_: string; 45 | 46 | /** editor model */ 47 | model_: monaco.editor.IModel; 48 | 49 | /** preserved state on tab switches */ 50 | view_state_: monaco.editor.ICodeEditorViewState; 51 | 52 | /** flag */ 53 | dirty_ = false; 54 | 55 | /** the last saved version, for comparison to AVID, for dirty check */ 56 | saved_version_ = 0; // last saved version ID 57 | 58 | /** local ID */ 59 | id_: number; 60 | 61 | /** rendered: not editable, show rendered content -- md and html? */ 62 | // rendered_ = false; 63 | type_: DocumentType; 64 | 65 | /** */ 66 | rendered_content_:string; 67 | 68 | /** node for rendered content. not preserved. */ 69 | rendered_content_node_:HTMLElement; 70 | 71 | /** override language (optional) */ 72 | overrideLanguage_: string; 73 | 74 | /** save pending to prevent loop with file watcher; not preserved */ 75 | save_pending_ = false; 76 | 77 | /** 78 | * revert pending to prevent side-effects (sigh). it should always be 79 | * an indication of bad design if you have to start working around side 80 | * effects. 81 | */ 82 | revert_pending_ = false; 83 | 84 | /** serialize */ 85 | toJSON() { 86 | return { 87 | label: this.label_, 88 | file_path: this.file_path_, 89 | view_state: this.view_state_, 90 | dirty: this.dirty_, 91 | overrideLanguage: this.overrideLanguage_, 92 | uri: this.model_ ? this.model_.uri : null, 93 | type: this.type_, 94 | saved_version: this.saved_version_, 95 | alternative_version_id: this.model_ ? this.model_.getAlternativeVersionId() : 0, 96 | text: this.model_ ? this.model_.getValue() : this.rendered_content_ 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /Console/src/editor/editor_status_bar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | const Constants = require("../../data/constants.json"); 21 | 22 | export interface EditorStackMessage { 23 | text:string; 24 | tag:any; 25 | } 26 | 27 | /** 28 | * status bar was originally just text, then it became a stack, 29 | * now it's a tagged stack. some of the cruft in here reflects 30 | * handling all the types at the same time. 31 | * 32 | * try to use tagged push/pop where possible. 33 | */ 34 | export class EditorStatusBar { 35 | 36 | /** main status bar node */ 37 | private node_: HTMLElement; 38 | 39 | /** text, left side */ 40 | private label_: HTMLElement; 41 | 42 | /** line/col (right side) */ 43 | private position_: HTMLElement; 44 | 45 | /** language (right side) */ 46 | private language_: HTMLElement; 47 | 48 | /** accessor */ 49 | public get node() { return this.node_; } 50 | 51 | /** accessor for content, not node */ 52 | // public set label(text) { this.label_.textContent = text; } 53 | 54 | /** stack-based (reverse) */ 55 | private stack_:EditorStackMessage[] = []; 56 | 57 | public PushMessage(text:string, tag:any = 0){ 58 | this.stack_.push({text, tag}); 59 | this.label_.textContent = text; 60 | } 61 | 62 | public PopMessage(tag?:any){ 63 | 64 | if(typeof tag === "undefined"){ 65 | // pop last 66 | if(this.stack_.length) this.stack_ = this.stack_.slice(0,this.stack_.length-1); 67 | } 68 | else { 69 | // pop all with tag 70 | this.stack_ = this.stack_.filter(item => item.tag !== tag); 71 | } 72 | 73 | if(this.stack_.length) this.label_.textContent = this.stack_[this.stack_.length-1].text; 74 | else this.label_.textContent = ""; 75 | } 76 | 77 | /** accessor for content, not node */ 78 | public set language(text) { this.language_.textContent = text; } 79 | 80 | /** accessor for content, not node: pass [line, col] */ 81 | public set position([line, column]) { 82 | if (null === line || null === column) { 83 | this.position_.textContent = ""; 84 | } 85 | else { 86 | this.position_.textContent = `${Constants.status.line} ${line}, ${Constants.status.column} ${column}`; 87 | } 88 | } 89 | 90 | /** show/hide position, for rendered documents */ 91 | public set show_position(show:boolean){ 92 | this.position_.style.display = show ? "" : "none"; 93 | } 94 | 95 | constructor() { 96 | 97 | this.node_ = document.createElement("div"); 98 | this.node_.classList.add("editor-status-bar"); 99 | 100 | this.label_ = document.createElement("div"); 101 | this.node_.appendChild(this.label_); 102 | 103 | // this node has flex-grow=1 to push other nodes to left and right 104 | let spacer = document.createElement("div"); 105 | spacer.classList.add("spacer"); 106 | this.node_.appendChild(spacer); 107 | 108 | this.position_ = document.createElement("div"); 109 | this.node_.appendChild(this.position_); 110 | 111 | this.language_ = document.createElement("div"); 112 | this.node_.appendChild(this.language_); 113 | 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /Console/src/io/management_pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import * as net from "net"; 21 | import * as messages from "../../generated/variable_pb.js"; 22 | 23 | /** 24 | * second pipe for out-of-band management tasks [FIXME: merge] 25 | * 26 | * this class doesn't strictly need formatted messages, but it's not 27 | * a lot of overhead so we might as well use the same types. 28 | */ 29 | export class Pipe2 { 30 | 31 | pipe_name_:string; 32 | client_:any; 33 | transaction_id_ = 1; 34 | 35 | HandleData(data){ 36 | console.info(`[2]: ${data}`); 37 | } 38 | 39 | HandleError(error){ 40 | console.error(`[2]: ${error}`); 41 | } 42 | 43 | /** 44 | * send message. wrapped up in a PB structure, framed. 45 | */ 46 | SendMessage(message){ 47 | 48 | let call = new messages.CallResponse(); 49 | call.setId(this.transaction_id_++); 50 | call.setWait(false); 51 | //call.setControlMessage(message); 52 | let function_call = new messages.CompositeFunctionCall; 53 | function_call.setTarget(messages.CallTarget.SYSTEM); 54 | function_call.setFunction(message); 55 | call.setFunctionCall(function_call); 56 | 57 | console.info(JSON.stringify(call.toObject(), undefined, 2)); 58 | 59 | let data = call.serializeBinary(); 60 | let frame_length = new Int32Array(1); 61 | let frame = new Uint8Array(data.length + 4); 62 | 63 | frame_length[0] = data.length; 64 | frame.set(new Uint8Array(frame_length), 0); 65 | frame.set(data, 4); 66 | this.client_.write(Buffer.from(frame as any)); // ts type is wrong? 67 | 68 | } 69 | 70 | /** initialize and connect to service */ 71 | Init(opts: any = {}) { 72 | 73 | this.pipe_name_ = opts.pipe_name || ""; 74 | 75 | return new Promise((resolve, reject) => { 76 | console.info(`connecting (2: ${this.pipe_name_})...`); 77 | 78 | let client = net.createConnection({ path: "\\\\.\\pipe\\" + this.pipe_name_ }, () => { 79 | console.info(`connected (2: ${this.pipe_name_})`); 80 | }); 81 | 82 | client.on("data", data => this.HandleData(data)); 83 | client.on("error", err => this.HandleError(err)); 84 | client.on("close", () => this.HandleError("closed")); 85 | client.on('end', () => { 86 | console.log('disconnected from pipe (2)'); 87 | }); 88 | 89 | this.client_ = client; 90 | 91 | }); 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Console/src/io/stdio_pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import * as net from "net"; 21 | import * as Rx from 'rxjs'; 22 | 23 | /** 24 | * third pipe (this is getting a little out of hand) for pass-through 25 | * stdio, without message wrapping. maybe temp, maybe not. TBD. 26 | * 27 | * FIXME: multiplex stdout/stderr in some fashion, or just use two pipes? 28 | */ 29 | 30 | export class StdIOPipe { 31 | 32 | pipe_name_:string; 33 | client_:any; 34 | 35 | private data_:Rx.Subject; 36 | public get data() { return this.data_; } 37 | 38 | constructor(){ 39 | this.data_ = new Rx.Subject(); 40 | } 41 | 42 | HandleError(error){ 43 | console.error(`[3]: ${error}`); 44 | } 45 | 46 | /** initialize and connect to service */ 47 | Init(opts: any = {}) { 48 | 49 | this.pipe_name_ = opts.pipe_name || ""; 50 | 51 | return new Promise((resolve, reject) => { 52 | console.info("connecting (3)..."); 53 | 54 | let client = net.createConnection({ path: "\\\\.\\pipe\\" + this.pipe_name_ }, () => { 55 | console.log('connected (3)'); 56 | }); 57 | 58 | client.on("data", data => this.data_.next(data.toString())); 59 | client.on("error", err => this.HandleError(err)); 60 | client.on("close", () => this.HandleError("closed")); 61 | client.on('end', () => { 62 | console.log('disconnected from pipe (3)'); 63 | }); 64 | 65 | this.client_ = client; 66 | 67 | }); 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Console/src/json.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | /* for importing json files */ 21 | declare module "*.json" { 22 | const value: any; 23 | export default value; 24 | } 25 | -------------------------------------------------------------------------------- /Console/src/shell/cursor_client_position_addon.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | /** 21 | * cursor position locator, implemented as terminal add-on. not 22 | * in love with patching prototype, but should be fine for electron 23 | */ 24 | const GetCursorPosition = function(terminal, offset_x = 0){ 25 | 26 | // character position 27 | let x = terminal.buffer.x; 28 | let y = terminal.buffer.y; 29 | 30 | // renderer dimensions 31 | let dimensions = terminal.renderer.dimensions; 32 | 33 | // position is relative to the canvas... although we should be 34 | // able to use the container node as a proxy. fixme: cache, or 35 | // use our node? (actually this is our node, we should just cache) 36 | let client_rect = (terminal.parent as HTMLElement).getBoundingClientRect(); 37 | 38 | // TAG: switching scaled -> actual to fix highdpi 39 | 40 | let rect = { 41 | left: client_rect.left + ((x+offset_x) * dimensions.actualCellWidth), 42 | right: client_rect.left + ((x+offset_x+1) * dimensions.actualCellWidth), 43 | top: client_rect.top + (y * dimensions.actualCellHeight), 44 | bottom: client_rect.top + ((y+1) * dimensions.actualCellHeight), 45 | }; 46 | 47 | return rect; 48 | 49 | } 50 | 51 | export const apply = function(terminalConstructor) { 52 | terminalConstructor.prototype.GetCursorPosition = function (offset_x = 0) { 53 | return GetCursorPosition(this, offset_x); // this will be terminal 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /Console/src/shell/custom-fit.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * original license (fit) 3 | * 4 | * Copyright (c) 2014 The xterm.js authors. All rights reserved. 5 | * @license MIT 6 | * 7 | * Fit terminal columns and rows to the dimensions of its DOM element. 8 | * 9 | * ## Approach 10 | * 11 | * Rows: Truncate the division of the terminal parent element height by the 12 | * terminal row height. 13 | * Columns: Truncate the division of the terminal parent element width by the 14 | * terminal character width (apply display: inline at the terminal 15 | * row and truncate its width with the current number of columns). 16 | * 17 | * 18 | */ 19 | 20 | /// 21 | 22 | import { Terminal } from 'xterm'; 23 | 24 | export interface IGeometry { 25 | rows: number; 26 | cols: number; 27 | } 28 | 29 | export function proposeGeometry(term: Terminal): IGeometry { 30 | if (!term.element.parentElement) { 31 | return null; 32 | } 33 | const parentElementStyle = window.getComputedStyle(term.element.parentElement); 34 | const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')); 35 | const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width'))); 36 | const elementStyle = window.getComputedStyle(term.element); 37 | const elementPadding = { 38 | top: parseInt(elementStyle.getPropertyValue('padding-top')), 39 | bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')), 40 | right: parseInt(elementStyle.getPropertyValue('padding-right')), 41 | left: parseInt(elementStyle.getPropertyValue('padding-left')) 42 | }; 43 | const elementPaddingVer = elementPadding.top + elementPadding.bottom; 44 | const elementPaddingHor = elementPadding.right + elementPadding.left; 45 | // const availableHeight = parentElementHeight - elementPaddingVer; 46 | const availableHeight = parentElementHeight - elementPaddingVer - (term).viewport.scrollBarWidth; 47 | const availableWidth = parentElementWidth - elementPaddingHor - (term).viewport.scrollBarWidth; 48 | const geometry = { 49 | cols: Math.floor(availableWidth / (term).renderer.dimensions.actualCellWidth), 50 | rows: Math.floor(availableHeight / (term).renderer.dimensions.actualCellHeight) 51 | }; 52 | 53 | return geometry; 54 | } 55 | 56 | export function fit(term: Terminal, minimum_columns = 0): void { 57 | 58 | if(!term['custom_fit_listener_attached']){ 59 | term['custom_fit_listener_attached'] = true; 60 | term['viewport'].viewportElement.addEventListener('scroll', e => { 61 | term['screenElement'].style.left = (-term['viewport'].viewportElement.scrollLeft) + "px"; 62 | }); 63 | } 64 | 65 | const geometry = proposeGeometry(term); 66 | geometry.cols = Math.max(geometry.cols, minimum_columns); 67 | if (geometry) { 68 | // Force a full render 69 | if (term.rows !== geometry.rows || term.cols !== geometry.cols) { 70 | (term).renderer.clear(); 71 | 72 | // we don't want to size the buffer based on target width, we want 73 | // to use max characters width (if it's wider) -- this can happen if 74 | // you resize without resetting. unfortunately these buffers are pre- 75 | // allocated. 76 | 77 | let max = geometry.cols - 2; // if it's wider 78 | term['buffers']._activeBuffer.lines.forEach(line => { 79 | let line_max = max; 80 | for( let i = max; i< line.length; i++ ){ 81 | if(line[i][0] !== 131840) line_max = i; 82 | } 83 | max = Math.max(max, line_max); 84 | }); 85 | 86 | let dimensions = term['renderer'].dimensions; 87 | 88 | let cols = Math.max(geometry.cols, max + 2); 89 | term.resize(cols, geometry.rows); 90 | 91 | term['viewport'].scrollArea.style.width = dimensions.canvasWidth + "px"; 92 | 93 | } 94 | } 95 | } 96 | 97 | export function apply(terminalConstructor: typeof Terminal): void { 98 | (terminalConstructor.prototype).proposeGeometry = function (): IGeometry { 99 | return proposeGeometry(this); 100 | }; 101 | 102 | (terminalConstructor.prototype).fit = function (minimum_columns = 0): void { 103 | fit(this, minimum_columns); 104 | }; 105 | 106 | } 107 | -------------------------------------------------------------------------------- /Console/src/shell/fontmetrics.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | /** 21 | * this is based on 22 | * 23 | * https://github.com/soulwire/FontMetrics 24 | * https://pomax.github.io/fontmetrics.js/fontmetrics.js 25 | * 26 | * both of which seem reasonable but aren't exactly what we need 27 | */ 28 | 29 | /** 30 | * returned font metrics 31 | */ 32 | export interface Metrics { 33 | ascent:number; 34 | descent:number; 35 | width:number; 36 | text?:string; 37 | } 38 | 39 | /** 40 | * this is not static, or global, because there's a possibility 41 | * we are (1) running async, and (2) running in different shells; 42 | * in that case we want to ensure separation. 43 | */ 44 | export class FontMetrics { 45 | 46 | canvas_:HTMLCanvasElement; 47 | context_:CanvasRenderingContext2D; 48 | padding_ = 0; 49 | cached_font_:string; 50 | 51 | public get context() { return this.context_ } 52 | 53 | constructor(){ 54 | this.canvas_ = document.createElement("canvas"); 55 | this.context_ = this.canvas_.getContext("2d"); 56 | } 57 | 58 | SetFont(font_family, font_size_px:number, font_weight = 400) { 59 | 60 | let font = `${font_weight} ${font_size_px}px ${font_family}`; 61 | if( this.cached_font_ === font ) return; 62 | 63 | this.padding_ = font_size_px * 0.5; 64 | this.canvas_.width = font_size_px * 2; 65 | this.canvas_.height = font_size_px * 2 + this.padding_; 66 | this.context_.textBaseline = 'top' 67 | this.context_.textAlign = 'center' 68 | this.context_.font = font; 69 | 70 | this.cached_font_ = font; 71 | 72 | } 73 | 74 | UpdateText(char) { 75 | this.context_.clearRect(0, 0, this.canvas_.width, this.canvas_.height); 76 | this.context_.fillText(char, this.canvas_.width / 2, this.padding_, this.canvas_.width) 77 | } 78 | 79 | GetPixels(char) { 80 | this.UpdateText(char); 81 | return this.context_.getImageData(0, 0, this.canvas_.width, this.canvas_.height).data; 82 | } 83 | 84 | GetFirstIndex(pixels) { 85 | for (let i = 3, n = pixels.length; i < n; i += 4) { 86 | if (pixels[i] > 0) return (i - 3) / 4; 87 | } 88 | return pixels.length; 89 | } 90 | 91 | GetLastIndex(pixels) { 92 | for (let i = pixels.length - 1; i >= 3; i -= 4) { 93 | if (pixels[i] > 0) return i / 4; 94 | } 95 | return 0; 96 | } 97 | 98 | MeasureTop(char){ 99 | return Math.round(this.GetFirstIndex(this.GetPixels(char)) / this.canvas_.width) - this.padding_; 100 | } 101 | 102 | MeasureBottom(char){ 103 | return Math.round(this.GetLastIndex(this.GetPixels(char)) / this.canvas_.width) - this.padding_; 104 | } 105 | 106 | Width(text) : number { 107 | return this.context_.measureText(text).width; 108 | } 109 | 110 | Measure(char) : Metrics { 111 | 112 | // use for width 113 | let text_metrics = this.context_.measureText(char); 114 | 115 | // use this one for baseline 116 | let baseline = this.MeasureBottom('n'); 117 | 118 | // now measure the actual char 119 | let ascent = this.MeasureTop(char); 120 | let descent = this.MeasureBottom(char); 121 | 122 | //console.info("TM", char, baseline, baseline - ascent, descent - baseline, this.cached_font_) 123 | 124 | return { 125 | ascent: (baseline - ascent), 126 | descent: Math.max(0, descent - baseline), 127 | width: text_metrics.width, 128 | text: char 129 | }; 130 | 131 | } 132 | 133 | } 134 | 135 | -------------------------------------------------------------------------------- /Console/src/shell/graphics_device.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import { Pipe } from '../io/pipe'; 21 | import { Metrics, FontMetrics } from './fontmetrics'; 22 | 23 | import * as Rx from 'rxjs'; 24 | import { AnnotationInfo } from './annotation_addon'; 25 | 26 | // I wanted this to be hidden... we should have a translation library 27 | import * as messages from "../../generated/variable_pb.js"; 28 | 29 | /** 30 | * base class for graphics devices. work in progress. 31 | */ 32 | export class GraphicsDevice { 33 | 34 | static LineJoin = { 35 | GE_ROUND_JOIN: 1, 36 | GE_MITRE_JOIN: 2, 37 | GE_BEVEL_JOIN: 3 38 | }; 39 | 40 | static LineCap = { 41 | GE_ROUND_CAP: 1, 42 | GE_BUTT_CAP: 2, 43 | GE_SQUARE_CAP: 3 44 | }; 45 | 46 | static font_metrics_ = new FontMetrics(); 47 | 48 | height_:number; 49 | width_:number; 50 | 51 | private static new_graphic_:Rx.Subject = new Rx.Subject(); 52 | 53 | public static get new_graphic() { return this.new_graphic_; } 54 | 55 | InsertGraphic(height:number, element:HTMLElement){ 56 | GraphicsDevice.new_graphic_.next({ height, element }); 57 | } 58 | 59 | static PointsToPixels(point_size:number){ 60 | return Math.round(point_size / 96 * 128 * 1000)/1000; 61 | } 62 | 63 | static FontFamily(context):string { 64 | 65 | if( context.fontface === 5 ) return "symbol"; 66 | 67 | switch(context.fontfamily){ 68 | case "mono": 69 | case "monospace": 70 | return "Consolas"; 71 | 72 | case "serif": 73 | return "Palatino Linotype"; 74 | 75 | case "sans": 76 | case "sans-serif": 77 | case "": 78 | return "Calibri"; 79 | 80 | default: 81 | return context.fontfamily; 82 | } 83 | } 84 | 85 | GraphicsResponse(x?:number[], y?:number[]){ 86 | 87 | let response = new messages.CallResponse(); 88 | let consoleMessage = new messages.Console(); 89 | let graphics = new messages.GraphicsCommand(); 90 | 91 | if(x) graphics.setXList(x); 92 | if(y) graphics.setYList(y); 93 | 94 | consoleMessage.setGraphics(graphics); 95 | response.setConsole(consoleMessage); 96 | return response; 97 | 98 | } 99 | 100 | // stub 101 | GraphicsCommand(message, command){} 102 | 103 | } 104 | -------------------------------------------------------------------------------- /Console/src/shell/language_interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import {Pipe, ConsoleMessage, ConsoleMessageType} from '../io/pipe'; 21 | import {Pipe2} from '../io/management_pipe'; 22 | import {StdIOPipe} from '../io/stdio_pipe'; 23 | import { TerminalImplementation } from './terminal_implementation'; 24 | 25 | import * as Rx from 'rxjs'; 26 | 27 | export interface LanguageNotification { 28 | type:string; 29 | data:any; 30 | } 31 | 32 | /** generic language interface */ 33 | export class LanguageInterface extends Rx.Subject { 34 | 35 | // language name. needs to match what comes out of the pipe 36 | static language_name_: string; 37 | 38 | // version, basically for julia 0.6 vs 0.7 39 | static target_version_ = [0, 0, 0]; 40 | 41 | // label for tab/id 42 | label_: string; 43 | 44 | // main comms pipe 45 | pipe_: Pipe; 46 | 47 | // pipe for control, cancel 48 | management_pipe_: Pipe2; 49 | 50 | // pipe for passthrough stdio 51 | stdout_pipe_: StdIOPipe; 52 | 53 | // pipe for passthrough stdio 54 | stderr_pipe_: StdIOPipe; 55 | 56 | // shell text colorizer/formatter 57 | formatter_:any = null; 58 | 59 | constructor(){ 60 | super(); 61 | } 62 | 63 | InitPipe(pipe:Pipe, name:string){ 64 | 65 | this.pipe_ = pipe; 66 | 67 | // console handler moved to terminal. FIXME: hide pipe, 68 | // pass through observables via accessors 69 | 70 | this.pipe_.control_messages.subscribe(message => { 71 | console.info( `CM (${this.constructor().language_name_})`, message ); 72 | if( message === "shutdown" ){ 73 | //this.terminal_.CleanUp(); 74 | //allow_close = true; // global 75 | //remote.getCurrentWindow().close(); 76 | console.warn( "ENOTIMPL: remote shutdown"); 77 | } 78 | }); 79 | 80 | } 81 | 82 | /** 83 | * stub for subclasses. we're introducing circular dependencies. 84 | */ 85 | AttachTerminal(terminal:TerminalImplementation){} 86 | 87 | Shutdown() : Promise { 88 | 89 | // ugh. use async. 90 | 91 | return new Promise((resolve, reject) => { 92 | if(this.management_pipe_){ 93 | // this.management_pipe_.Close(); // no close method? 94 | } 95 | // if( this.terminal_ ){ this.terminal_.CleanUp(); } 96 | if( this.pipe_ ){ 97 | this.pipe_.Close().then(() => { 98 | return resolve(); 99 | }).catch(() => { 100 | return resolve(); 101 | }); 102 | } 103 | else { 104 | return resolve(); 105 | } 106 | }); 107 | } 108 | 109 | AutocompleteCallback(buffer:string, position:number) : Promise { 110 | return null; 111 | } 112 | 113 | ExecCallback(buffer:string) : Promise { 114 | return null; 115 | } 116 | 117 | BreakCallback() {} 118 | 119 | } 120 | -------------------------------------------------------------------------------- /Console/src/shell/language_interface_julia-0.7.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import { LanguageInterface } from './language_interface'; 21 | import {Pipe, ConsoleMessage, ConsoleMessageType} from '../io/pipe'; 22 | import {Pipe2} from '../io/management_pipe'; 23 | import {StdIOPipe} from '../io/stdio_pipe'; 24 | 25 | import { MenuUtilities } from '../ui/menu_utilities'; 26 | 27 | /** specialization: Julia */ 28 | export class Julia07Interface extends LanguageInterface { 29 | 30 | static language_name_ = "Julia"; 31 | static target_version_ = [ 0, 7, 0 ]; 32 | 33 | constructor(){ 34 | super(); 35 | MenuUtilities.events.subscribe(event => { 36 | switch(event.id){ 37 | case "main.packages.julia.install-packages": 38 | console.info("Julia install packages"); 39 | break; 40 | } 41 | }); 42 | } 43 | 44 | InitPipe(pipe:Pipe, name:string){ 45 | super.InitPipe(pipe, name); 46 | this.management_pipe_ = new Pipe2(); 47 | this.management_pipe_.Init({pipe_name: name + "-M"}); 48 | 49 | this.stdout_pipe_ = new StdIOPipe(); 50 | this.stdout_pipe_.Init({pipe_name: name + "-STDOUT"}); 51 | 52 | this.stderr_pipe_ = new StdIOPipe(); 53 | this.stderr_pipe_.Init({pipe_name: name + "-STDERR"}); 54 | 55 | } 56 | 57 | async AutocompleteCallback(buffer:string, position:number) { 58 | 59 | return null; 60 | 61 | // FIXME: need to normalize AC data structure (output) 62 | 63 | buffer = buffer.replace( /\\/g, '\\\\').replace( /"/g, '\\"' ); 64 | buffer = buffer.replace( /\$/g, "\\$"); // julia string interpolations 65 | 66 | let x = await this.pipe_.Internal(`BERT.Autocomplete("${buffer}",${position})`); 67 | 68 | let arr:Array = (Array.isArray(x) ? x as Array : []) 69 | 70 | // slightly different breaks (+.). allow leading backslash (escape) 71 | let token = buffer.replace(/\\\\/g, "\\").replace(/^.*[^\w\\]/, ""); 72 | // console.info( `tok "${token}"`) 73 | 74 | // check if these are function signatures 75 | if(arr.length && /\(/.test(arr[0])){ 76 | arr = arr.map(x => x.replace(/\)\s+in.*$/, ")" )); 77 | 78 | // sort by number of arguments, then length 79 | arr.sort((a, b) => { 80 | let ac = a.replace(/[^,]/g, "").length; 81 | let bc = b.replace(/[^,]/g, "").length; 82 | return (ac-bc) || (a.length - b.length); 83 | }); 84 | 85 | return { token, candidates: arr }; 86 | } 87 | 88 | return ({ comps: arr.join("\n"), token }); 89 | 90 | } 91 | 92 | async ExecCallback(buffer:string){ 93 | let result = await this.pipe_.ShellExec(buffer); 94 | if( result === -1 ) return { pop_stack: true }; 95 | return { text: result }; 96 | } 97 | 98 | BreakCallback(){ 99 | this.management_pipe_.SendMessage("break"); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /Console/src/shell/language_interface_julia.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import { LanguageInterface } from './language_interface'; 21 | import {Pipe, ConsoleMessage, ConsoleMessageType} from '../io/pipe'; 22 | import {Pipe2} from '../io/management_pipe'; 23 | import {StdIOPipe} from '../io/stdio_pipe'; 24 | 25 | import { MenuUtilities } from '../ui/menu_utilities'; 26 | 27 | /** specialization: Julia */ 28 | export class JuliaInterface extends LanguageInterface { 29 | 30 | static language_name_ = "Julia"; 31 | static target_version_ = [ 0, 6, 0 ]; 32 | 33 | constructor(){ 34 | super(); 35 | MenuUtilities.events.subscribe(event => { 36 | switch(event.id){ 37 | case "main.packages.julia.install-packages": 38 | console.info("Julia install packages"); 39 | break; 40 | } 41 | }); 42 | } 43 | 44 | InitPipe(pipe:Pipe, name:string){ 45 | super.InitPipe(pipe, name); 46 | this.management_pipe_ = new Pipe2(); 47 | this.management_pipe_.Init({pipe_name: name + "-M"}); 48 | 49 | this.stdout_pipe_ = new StdIOPipe(); 50 | this.stdout_pipe_.Init({pipe_name: name + "-STDOUT"}); 51 | 52 | this.stderr_pipe_ = new StdIOPipe(); 53 | this.stderr_pipe_.Init({pipe_name: name + "-STDERR"}); 54 | 55 | } 56 | 57 | async AutocompleteCallback(buffer:string, position:number) { 58 | 59 | // FIXME: need to normalize AC data structure (output) 60 | 61 | buffer = buffer.replace( /\\/g, '\\\\').replace( /"/g, '\\"' ); 62 | buffer = buffer.replace( /\$/g, "\\$"); // julia string interpolations 63 | 64 | let x = await this.pipe_.Internal(`BERT.Autocomplete("${buffer}",${position})`); 65 | 66 | let arr:Array = (Array.isArray(x) ? x as Array : []) 67 | 68 | // slightly different breaks (+.). allow leading backslash (escape) 69 | let token = buffer.replace(/\\\\/g, "\\").replace(/^.*[^\w\\]/, ""); 70 | // console.info( `tok "${token}"`) 71 | 72 | // check if these are function signatures 73 | if(arr.length && /\(/.test(arr[0])){ 74 | arr = arr.map(x => x.replace(/\)\s+in.*$/, ")" )); 75 | 76 | // sort by number of arguments, then length 77 | arr.sort((a, b) => { 78 | let ac = a.replace(/[^,]/g, "").length; 79 | let bc = b.replace(/[^,]/g, "").length; 80 | return (ac-bc) || (a.length - b.length); 81 | }); 82 | 83 | return { token, candidates: arr }; 84 | } 85 | 86 | return ({ comps: arr.join("\n"), token }); 87 | 88 | } 89 | 90 | async ExecCallback(buffer:string){ 91 | let result = await this.pipe_.ShellExec(buffer); 92 | if( result === -1 ) return { pop_stack: true }; 93 | return { text: result }; 94 | } 95 | 96 | BreakCallback(){ 97 | this.management_pipe_.SendMessage("break"); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /Console/src/ui/user_stylesheet.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | import * as less from 'less'; 21 | import * as path from 'path'; 22 | import * as fs from 'fs'; 23 | import { FileWatcher } from '../common/file_watcher'; 24 | 25 | export class UserStylesheet { 26 | 27 | private static stylesheet_path_ = path.join( 28 | process.env['BERT_HOME'], "user-stylesheet.less"); 29 | 30 | public static get stylesheet_path() { return this.stylesheet_path_; } 31 | 32 | private static node:HTMLElement; 33 | 34 | static Attach(){ 35 | 36 | this.node = document.createElement("style"); 37 | this.node.setAttribute("type", "text/css"); 38 | document.head.appendChild(this.node); 39 | 40 | this.Load().then(() => { 41 | 42 | // subscribe to changes 43 | FileWatcher.Watch(this.stylesheet_path_); 44 | FileWatcher.events.filter(x => x === this.stylesheet_path_).subscribe(x => { 45 | this.Load().then(() => {}).catch(err => { 46 | console.warn(err); 47 | }); 48 | }); 49 | 50 | }).catch(err => { 51 | console.warn(err); 52 | }); 53 | } 54 | 55 | static Insert(){ 56 | 57 | } 58 | 59 | static Load(){ 60 | return new Promise((resolve, reject) => { 61 | fs.readFile(this.stylesheet_path_, "utf8", (err, data) => { 62 | if(err){ 63 | return reject("user stylesheet not found"); 64 | } 65 | less.render(data, {sourceMap:{}}).then(output => { 66 | this.node.innerText = output.css; 67 | resolve(); 68 | }).catch(err => { 69 | return reject("less error: " + err); 70 | }); 71 | }); 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Console/style/alert.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @import "./common.less"; 21 | 22 | .alert_overlay { 23 | 24 | z-index: 2000; 25 | position: absolute; 26 | top: 0; 27 | left: 0; 28 | right: 0; 29 | bottom: 0; 30 | background: rgba(0, 0, 0, .05); 31 | // background: transparent; 32 | 33 | position: flex; 34 | display: none; 35 | flex-direction: row; 36 | justify-content: center; 37 | align-items: flex-start; 38 | font-family: 'Segoe UI'; 39 | 40 | .alert_container { 41 | background: #fff; 42 | border-radius: 3px; 43 | width: 60%; 44 | margin-top: 3em; 45 | padding: 0px; 46 | display: flex; 47 | flex-direction: row; 48 | box-shadow: 0px 5px 12px 0px rgba(0,0,0,.2); 49 | 50 | opacity: 0; 51 | transition: opacity .2s; 52 | 53 | button { 54 | padding: 0; 55 | margin: 0 0 0 0; 56 | border: none; 57 | background: transparent; 58 | cursor: pointer; 59 | outline: none; 60 | color: inherit; 61 | font-family: inherit; 62 | font-size: inherit; 63 | &:hover { text-decoration: underline; } 64 | } 65 | 66 | & > div { 67 | min-height: 2.75em; 68 | padding: 0; 69 | white-space: nowrap; 70 | margin-top: auto; 71 | display: flex; 72 | flex-direction: row; 73 | align-items: center; 74 | } 75 | 76 | .alert_title { 77 | font-weight: 600; 78 | border-left: 4px solid #66cc99; 79 | padding-left: .75em; 80 | } 81 | 82 | .alert_message { 83 | flex-grow: 1; 84 | background: #fff; 85 | padding-left: 1em; 86 | color: #444; 87 | 88 | button { 89 | text-decoration: underline; 90 | } 91 | 92 | } 93 | 94 | .alert_buttons { 95 | background: #66cc99; 96 | color: #fff; 97 | padding-left: .75em; 98 | padding-right: .75em; 99 | } 100 | 101 | } 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Console/style/common.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @terminal-box-shadow: 0px 2px 3px 0px rgba(0,0,0,0.25); 21 | 22 | @ui-font-family: Segoe UI; 23 | -------------------------------------------------------------------------------- /Console/style/dialog.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @import "./common.less"; 21 | 22 | .dialog_overlay { 23 | 24 | z-index: 2000; 25 | position: absolute; 26 | top: 0; 27 | left: 0; 28 | right: 0; 29 | bottom: 0; 30 | background: rgba(0, 0, 0, .1); 31 | position: flex; 32 | display: none; 33 | flex-direction: row; 34 | justify-content: center; 35 | align-items: center; 36 | 37 | .dialog_container { 38 | 39 | display: flex; 40 | flex-direction: column; 41 | background: #fff; 42 | position: relative; 43 | border-top: 5px solid #66cc99; 44 | border-radius: 3px; 45 | min-width: 400px; 46 | height: 300px; 47 | box-shadow: @terminal-box-shadow; 48 | font-family: Segoe UI; 49 | 50 | color: #666; 51 | 52 | .dialog_header { 53 | 54 | color: #333; 55 | padding: .5em 1em; 56 | 57 | .dialog_title { 58 | font-weight: 600; 59 | font-size: 16px; 60 | padding: 0; 61 | margin: 0; 62 | } 63 | 64 | position: relative; 65 | min-height: 3em; 66 | 67 | .dialog_close_x { 68 | 69 | position: absolute; 70 | right: 3px; 71 | top: 2px; 72 | cursor: default; 73 | color: #999; 74 | 75 | &:hover { color: #333; } 76 | 77 | &::after { 78 | font-size: 18px; 79 | font-family: icomoon; 80 | content: '\e904'; 81 | } 82 | } 83 | 84 | } 85 | 86 | .dialog_body { 87 | flex-grow: 1; 88 | margin: .5em 1em; 89 | position: relative; 90 | } 91 | 92 | .dialog_footer { 93 | 94 | min-height: 1em; 95 | padding: 6px; 96 | display: flex; 97 | flex-direction: row; 98 | align-items: center; 99 | 100 | margin: 0em .5em; 101 | 102 | .dialog_status { 103 | flex-grow: 1; 104 | } 105 | 106 | .dialog_buttons { 107 | 108 | button { 109 | 110 | &.default { 111 | 112 | background: #66cc99; 113 | color: #fff; 114 | 115 | &:hover { 116 | background: #efefef; 117 | color: #66cc99; 118 | } 119 | 120 | &:active { 121 | background: #f2f2f2; 122 | color: #66cc99; 123 | } 124 | 125 | } 126 | 127 | background: #c0c0c0; 128 | color: #fff; 129 | outline: none; 130 | 131 | &:hover { 132 | background: #efefef; 133 | color: #aaa; 134 | } 135 | 136 | &:active { 137 | background: #f2f2f2; 138 | color: #aaa; 139 | } 140 | 141 | min-height: 27px; 142 | min-width: 80px; 143 | border: 0; // border: 1px solid #ccc; 144 | border-radius: 2px; 145 | margin-right: .5em; 146 | &:last-child { margin-right: 0; } 147 | } 148 | 149 | button:first-child { 150 | display: inline-block; 151 | } 152 | 153 | } 154 | 155 | } 156 | 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /Console/style/editor.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @import "./common.less"; 21 | 22 | .editor-container { 23 | position: relative; 24 | display: flex; 25 | flex-direction: column; 26 | } 27 | 28 | .editor-status-bar { 29 | 30 | border-top: 1px solid #ccc; 31 | color: #333; 32 | 33 | display: flex; 34 | flex-direction: row; 35 | background: #eee; 36 | align-items: center; 37 | height: 2em; 38 | font-family: @ui-font-family; 39 | font-size: 12px; 40 | overflow: hidden; 41 | 42 | > div { 43 | padding-left: .5em; 44 | padding-right: .5em; 45 | display: inline-block; 46 | &.spacer { flex-grow: 1; } 47 | white-space: nowrap; 48 | text-overflow: ellipsis; 49 | } 50 | 51 | } 52 | 53 | .editor-tabs { 54 | position: relative; 55 | flex-grow: 1; 56 | } 57 | 58 | .editor-rendered-viewer { 59 | position: absolute; 60 | top: 0px; 61 | left: 0px; 62 | right: 0px; 63 | bottom: 0px; 64 | background: #fff; 65 | overflow-y: scroll; 66 | overflow-x: auto; 67 | 68 | } 69 | 70 | .editor-editor { 71 | background: #fff; 72 | position: absolute; 73 | top: 0px; 74 | left: 0px; 75 | right: 0px; 76 | bottom: 0px; 77 | 78 | // if you want content in the editor background (toggled on open file), 79 | // use this after block. either content or background (for text, maybe 80 | // use svg background) 81 | 82 | &::after { 83 | position: absolute; 84 | top: 50%; 85 | left: 0px; 86 | right: 0px; 87 | font-family: icomoon; 88 | font-size: 30px; 89 | color: #999; 90 | content: '\e903'; 91 | text-align: center; 92 | } 93 | 94 | &[data-mode-id]::after { 95 | content: "" 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Console/style/markdown.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | .markdown { 21 | 22 | padding: 1em; 23 | 24 | font-family: Segoe UI; 25 | 26 | h1, h2, h3 { 27 | font-weight: 300; 28 | padding: 3px 10px; 29 | } 30 | 31 | h1 { 32 | border-bottom: 3px double #ddd; 33 | font-size: 21px; 34 | 35 | &:not(:first-child){ 36 | -webkit-margin-before: 1.67em; // default is 0.67em; 37 | } 38 | 39 | } 40 | 41 | h2 { 42 | font-size: 18px; 43 | padding: 3px 16px; 44 | border-bottom: 1px solid #ddd; 45 | } 46 | 47 | h3 { 48 | padding: 3px 16px; 49 | } 50 | 51 | & code { 52 | font-family: consolas; 53 | } 54 | 55 | pre { 56 | background: #cef; 57 | color: #333; 58 | padding: 7px 10px; 59 | border-radius: 3px; 60 | font-size: 13px; 61 | } 62 | 63 | p { 64 | padding: 3px 10px; 65 | code { 66 | background: #cef; 67 | } 68 | } 69 | 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /Console/style/splitter_window.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @import "./common.less"; 21 | 22 | /** defaults to horizontal orientation (left and right) */ 23 | .splitter-parent { 24 | 25 | display: flex; 26 | flex-direction: row; 27 | 28 | .splitter-child { 29 | 30 | &:first-child { 31 | order: 1; 32 | } 33 | 34 | &:nth-child(2) { 35 | order: 3; 36 | } 37 | 38 | } 39 | 40 | 41 | .splitter-splitter { 42 | 43 | width: 1px; 44 | background: #bbb; 45 | 46 | z-index: 200; // we're now layering shells, so this needs to be > 100 47 | 48 | /* 49 | width: 13px; 50 | background: #eee; 51 | //border-left: 1px solid #ddd; 52 | //border-right: 1px solid #ddd; 53 | */ 54 | 55 | height: auto; 56 | cursor: ew-resize; 57 | order: 2; 58 | position: relative; 59 | overflow: visible; 60 | 61 | &:after { 62 | position: absolute; 63 | width: 13px; 64 | bottom: 0; 65 | top: 0; 66 | left: -6px; 67 | //background: rgba(0,0,0,.1); 68 | //left: 0px; 69 | content: ' '; 70 | overflow: hidden; 71 | } 72 | 73 | } 74 | 75 | } 76 | 77 | /** vertical orientation (top and bottom) */ 78 | .splitter-parent.splitter-orientation-vertical { 79 | flex-direction: column; 80 | 81 | .splitter-splitter { 82 | width: auto; 83 | height: 1px; 84 | cursor: ns-resize; 85 | 86 | &:after { 87 | height: 13px; 88 | right: 0; 89 | width: 100%; 90 | left: 0; 91 | top: -6px; 92 | } 93 | 94 | } 95 | } 96 | 97 | /** drag overlay. only need one for any number of splitters. */ 98 | #splitter-drag-overlay { 99 | 100 | z-index: 9999; 101 | position: absolute; 102 | top: 0px; 103 | left: 0px; 104 | right: 0px; 105 | bottom: 0px; 106 | cursor: ew-resize; 107 | 108 | justify-content: center; 109 | align-items: center; 110 | display: none; 111 | 112 | &.visible { display: flex; } 113 | 114 | &.splitter-orientation-vertical { 115 | cursor: ns-resize; 116 | } 117 | 118 | /** indicator */ 119 | div { 120 | position: relative; 121 | border-radius: 2px; 122 | color: #666; 123 | padding: 4px 10px; 124 | background: rgba( 255, 255, 255, .85); 125 | box-shadow: @terminal-box-shadow; 126 | } 127 | 128 | } 129 | 130 | -------------------------------------------------------------------------------- /Console/style/style.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | * { 21 | box-sizing: border-box; 22 | } 23 | 24 | html, body { 25 | position: relative; 26 | padding: 0; 27 | margin: 0; 28 | height: 100%; 29 | font-family: consolas; 30 | font-size: 14px; 31 | } 32 | 33 | #main-window { 34 | position: absolute; 35 | top: 0px; 36 | left: 0px; 37 | right: 0px; 38 | bottom: 0px; 39 | overflow:hidden; 40 | } 41 | 42 | @import "terminal3.less"; 43 | @import "terminal_overlay.less"; 44 | @import "tab_panel.less"; 45 | @import "editor.less"; 46 | @import "splitter_window.less"; 47 | @import "dialog.less"; 48 | @import "markdown.less"; 49 | @import "alert.less"; 50 | @import "virtual-list.less"; 51 | -------------------------------------------------------------------------------- /Console/style/terminal3.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | .xterm-annotation-node { 21 | border: 1px solid #ccc; 22 | margin-left: 1em; 23 | box-shadow: 0px 5px 12px 0px rgba(0,0,0,.25); 24 | 25 | // we raise these nodes above the xterm mouse event 26 | // layer, so we can get graphics as targets on right 27 | // clicks (context menu). not sure what the actual 28 | // z-index of the mouse layer is, or if it's constant. 29 | 30 | z-index: 4; 31 | } 32 | 33 | // sigh 34 | 35 | .terminal-child { 36 | position: absolute; 37 | top: 0px; 38 | left: 0px; // left: .5em; // this bumps up against the separator. 39 | right: 0px; 40 | bottom: 0px; 41 | overflow: hidden; 42 | 43 | &>div { 44 | position: absolute; 45 | top: 0px; 46 | left: .5em; // this bumps up against the separator. 47 | right: 0px; 48 | bottom: 0px; 49 | overflow: hidden; 50 | } 51 | 52 | } 53 | 54 | // some overrides for custom terminal: we allow wide buffers 55 | // with horizontal scrolling (...) 56 | 57 | .terminal.xterm { 58 | position: absolute; 59 | top: 0px; 60 | bottom: 0px; 61 | right: 0px; 62 | left: 0px; 63 | } 64 | 65 | .terminal.xterm .xterm-viewport { 66 | overflow-x: scroll; 67 | z-index: 2; 68 | background-color: transparent !important; 69 | } 70 | 71 | .xterm-graphics-node { 72 | 73 | /* 74 | * we want to guarantee the size of the canvas, otherwise it will 75 | * be scaled and look fuzzy, particularly text 76 | */ 77 | box-sizing: content-box; 78 | } 79 | -------------------------------------------------------------------------------- /Console/style/terminal_overlay.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | @import "./common.less"; 21 | 22 | // --- busy -------------------------------------------------------------------- 23 | 24 | @keyframes spin { 100% { transform:rotate(360deg); } } 25 | 26 | .terminal:after { 27 | font-family: cogs; 28 | font-style: normal; 29 | font-weight: normal; 30 | line-height: 1; 31 | -webkit-font-smoothing: antialiased; 32 | content: '\0056'; 33 | position: fixed; 34 | //bottom: 4px; 35 | bottom: 20px; 36 | right: 20px; 37 | z-index: 999; 38 | font-size: 45px; 39 | opacity: 0; 40 | transition: opacity 0.25s; 41 | animation: spin 5s linear infinite; 42 | } 43 | 44 | .busy .terminal:after { 45 | opacity: .25; 46 | } 47 | 48 | // --- tooltip ----------------------------------------------------------------- 49 | 50 | .terminal-tooltip { 51 | background: rgb(255, 255, 192); 52 | border: 1px solid yellow; 53 | border-radius: 2px; 54 | padding: 2px; 55 | position: absolute; 56 | z-index: 100; 57 | font-family: consolas; 58 | font-size: 12px; 59 | transition: opacity .1s; 60 | opacity: 0; 61 | top: 0px; 62 | left: -1000px; 63 | } 64 | 65 | // --- autocomplete ------------------------------------------------------------ 66 | 67 | .terminal-completion-list { 68 | margin: 0; 69 | padding: 0; 70 | 71 | background: #fff; 72 | border: 1px solid #ececec; 73 | position: absolute; 74 | z-index: 100; 75 | top: 0px; 76 | left: -1000px; 77 | font-family: consolas; 78 | font-size: 12px; 79 | transition: opacity .1s; 80 | opacity: 0; 81 | box-shadow: @terminal-box-shadow; 82 | overflow: auto; 83 | max-height: 10em; 84 | 85 | } 86 | 87 | .terminal-completion-list li { 88 | width: 100%; 89 | cursor: default; 90 | padding: 1px 4px; 91 | } 92 | 93 | .terminal-completion-list .active { 94 | color: #fff; 95 | background: #3879d9; 96 | } 97 | -------------------------------------------------------------------------------- /Console/style/virtual-list.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #list-measurement-node { 21 | position: absolute; 22 | top: -1000px; 23 | left: -1000px; 24 | } 25 | 26 | .list-container { 27 | position: absolute; 28 | top: 0px; 29 | bottom: 0px; 30 | left: 0px; 31 | right: 0px; 32 | display: flex; 33 | flex-direction: column; 34 | align-items: stretch; 35 | } 36 | 37 | .list-header { 38 | padding-bottom: .5em; 39 | } 40 | 41 | .list-body { 42 | overflow: scroll; 43 | flex-grow: 1; 44 | border: 1px solid #ccc; 45 | } 46 | 47 | .list-inner-body { 48 | position: relative; 49 | overflow: hidden; 50 | } 51 | 52 | .list-body-entry { 53 | white-space: nowrap; 54 | padding: 0; 55 | margin: 0; 56 | } 57 | 58 | // FIXME: this should probably move 59 | 60 | // hack: we need this node or the containing flex layout doesn't work; 61 | // the header gets compressed because it's not measured properly 62 | 63 | .list-header-layout { 64 | 65 | display: flex; 66 | align-items: center; 67 | 68 | div { 69 | flex-grow: 2; 70 | } 71 | 72 | input { 73 | flex-grow: 1; 74 | display: block; 75 | border-radius: 2px; 76 | border: 1px solid #ccc; 77 | font-family: inherit; 78 | font-size: inherit; 79 | padding: 1px .35em; 80 | } 81 | } 82 | 83 | .dialog_container.cran-mirror-chooser { 84 | height: 70%; 85 | width: 30%; 86 | } 87 | 88 | .dialog_container.cran-package-chooser { 89 | height: 70%; 90 | width: 50%; 91 | } 92 | 93 | .cran-package-list, .cran-mirror-list { 94 | font-family: "Segoe UI"; 95 | 96 | .list-body-entry { 97 | padding: 3px 6px; 98 | border-bottom: 1px solid #ccc; 99 | width: auto; 100 | } 101 | } 102 | 103 | .cran-package-list { 104 | 105 | .list-body-entry { 106 | 107 | &.installed { 108 | color: #aaa; 109 | } 110 | 111 | &.selected { 112 | background: #66cc99; 113 | color: #fff; 114 | } 115 | 116 | display: flex; 117 | flex-direction: row; 118 | 119 | .list-entry-name { 120 | cursor: default; 121 | font-weight: 600; 122 | } 123 | 124 | .list-entry-description { 125 | cursor: default; 126 | padding-left: .5em; 127 | } 128 | } 129 | } 130 | 131 | .cran-mirror-list { 132 | .list-body-entry { 133 | 134 | .list-entry-header { 135 | cursor: default; 136 | } 137 | 138 | .list-entry-subheader { 139 | cursor: default; 140 | font-size: .8em; 141 | } 142 | 143 | &.selected { 144 | background: #66cc99; 145 | color: #fff; 146 | } 147 | 148 | } 149 | } 150 | 151 | -------------------------------------------------------------------------------- /Console/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files":[ 3 | "src/renderer.ts" 4 | ], 5 | "compilerOptions": { 6 | "outDir": "build", 7 | "target": "es5", 8 | "inlineSourceMap": true, 9 | "inlineSources": true, 10 | "moduleResolution": "node", 11 | "lib": [ "es2015", "dom", "es5" ] 12 | } 13 | } -------------------------------------------------------------------------------- /Console/typings.d.ts: -------------------------------------------------------------------------------- 1 | 2 | declare module "*.json" { 3 | const value: any; 4 | export default value; 5 | } 6 | -------------------------------------------------------------------------------- /ControlJulia-0.7/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | *.vcxproj.user 3 | -------------------------------------------------------------------------------- /ControlJulia-0.7/ControlJulia07.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {2cdc21e6-7e2a-4a9f-891e-733c69ebc86c} 18 | 19 | 20 | {f7b2ec5b-4242-4b44-87a6-77b682f4697c} 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | PB 32 | 33 | 34 | Common 35 | 36 | 37 | Common 38 | 39 | 40 | Common 41 | 42 | 43 | Common 44 | 45 | 46 | Common 47 | 48 | 49 | Common 50 | 51 | 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | PB 61 | 62 | 63 | Common 64 | 65 | 66 | Common 67 | 68 | 69 | Common 70 | 71 | 72 | Common 73 | 74 | 75 | -------------------------------------------------------------------------------- /ControlJulia-0.7/include/control_julia.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "variable.pb.h" 39 | #include "message_utilities.h" 40 | #include "pipe.h" 41 | #include "process_exit_codes.h" 42 | -------------------------------------------------------------------------------- /ControlJulia-0.7/include/io_redirector.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __IO_REDIRECTOR_H 3 | #define __IO_REDIRECTOR_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define IOR_BUFFER_SIZE (1024 * 4) 11 | 12 | /** 13 | * apparently we can't override stdout with an async pipe. we can use 14 | * a synchronous pipe, and pipe _that_ into an async pipe. which seems 15 | * like a big headache (not to mention a waste of resources), but maybe 16 | * is still the best solution. 17 | * 18 | * we could also just have the sync pipe write buffers and set events, 19 | * which would work but will require some additional locks. 20 | */ 21 | class IORedirector { 22 | 23 | protected: 24 | static unsigned __stdcall ThreadFunc(void *argument) { 25 | IORedirector* instance = static_cast(argument); 26 | instance->StartThread(); 27 | return 0; 28 | } 29 | 30 | protected: 31 | int id_; 32 | bool run_; 33 | CRITICAL_SECTION critical_section_; 34 | char *buffer_; 35 | std::string name; 36 | std::string text_; 37 | 38 | public: 39 | HANDLE data_available_; 40 | 41 | public: 42 | IORedirector() { 43 | buffer_ = new char(IOR_BUFFER_SIZE); 44 | data_available_ = CreateEvent(0, true, false, 0); 45 | InitializeCriticalSectionAndSpinCount(&critical_section_, 0x00000400); 46 | } 47 | 48 | protected: 49 | 50 | void StartThread() { 51 | 52 | char *buffer = new char[IOR_BUFFER_SIZE]; 53 | DWORD bytes_read; 54 | 55 | HANDLE pipe_handle = CreateFileA(name.c_str(), GENERIC_READ, 0, 56 | 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 57 | 58 | while (run_) { 59 | bytes_read = 0; 60 | ReadFile(pipe_handle, buffer, IOR_BUFFER_SIZE, &bytes_read, 0); 61 | if (bytes_read > 0) { 62 | EnterCriticalSection(&critical_section_); 63 | 64 | // FIXME: we should impose some sort of reasonable limit on this buffer 65 | 66 | text_.append(buffer, bytes_read); 67 | 68 | LeaveCriticalSection(&critical_section_); 69 | 70 | SetEvent(data_available_); 71 | } 72 | 73 | } 74 | 75 | delete[] buffer; 76 | 77 | } 78 | 79 | public: 80 | 81 | void GetData(std::string &target) { 82 | 83 | // we should move the string to pass it out and then have a 84 | // new, empty buffer on this side. maybe? FIXME 85 | 86 | EnterCriticalSection(&critical_section_); 87 | target = text_; 88 | text_ = ""; 89 | LeaveCriticalSection(&critical_section_); 90 | 91 | } 92 | 93 | void Stop() { 94 | run_ = false; 95 | } 96 | 97 | void Start(FILE *file) { 98 | 99 | std::stringstream sync_pipe_name; 100 | sync_pipe_name << "\\\\.\\pipe\\iop." << _getpid() << "." << _fileno(file); 101 | 102 | run_ = true; 103 | name = sync_pipe_name.str(); 104 | 105 | HANDLE pipe_handle = CreateNamedPipeA(name.c_str(), 106 | PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 107 | 4, 0, IOR_BUFFER_SIZE, 1000, NULL); 108 | 109 | int stream = _open_osfhandle((intptr_t)pipe_handle, 0); 110 | FILE *write_file = _fdopen(stream, "wt"); 111 | _dup2(_fileno(write_file), _fileno(file)); 112 | setvbuf(file, NULL, _IONBF, 0); 113 | 114 | _beginthreadex(0, 0, IORedirector::ThreadFunc, static_cast(this), 0, 0); 115 | 116 | ConnectNamedPipe(pipe_handle, 0); 117 | 118 | DWORD mode; 119 | 120 | DWORD x = FILE_TYPE_PIPE; 121 | 122 | std::cerr << "GFT for pipe handle: " << GetFileType(pipe_handle) << std::endl; 123 | 124 | BOOL gcm = GetConsoleMode(pipe_handle, &mode); 125 | std::cerr << "GCM for pipe handle returned " << (gcm ? "TRUE" : "FALSE") << ", mode is " << mode << std::endl; 126 | 127 | } 128 | 129 | }; 130 | 131 | #endif // #ifndef __IO_REDIRECTOR_H 132 | -------------------------------------------------------------------------------- /ControlJulia-0.7/include/julia_interface.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "variable.pb.h" 40 | #include "string_utilities.h" 41 | #include "message_utilities.h" 42 | 43 | typedef enum { 44 | Error = 0, 45 | Success, 46 | Incomplete 47 | } 48 | ExecResult; 49 | 50 | /** startup */ 51 | void JuliaInit(); 52 | 53 | /** shutdown */ 54 | void JuliaShutdown(); 55 | 56 | /** get version so we can gate/limit */ 57 | void JuliaGetVersion(int32_t *major, int32_t *minor, int32_t *patch); 58 | 59 | /** exec in a shell context; as if we're typing at the repl */ 60 | ExecResult JuliaShellExec(const std::string &command, const std::string &shell_buffer); 61 | 62 | /** returns a list of functions exported to excel */ 63 | void ListScriptFunctions(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 64 | 65 | /** runs arbitrary julia code */ 66 | void JuliaExec(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 67 | 68 | /** runs julia function by name, optionally with arguments */ 69 | void JuliaCall(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 70 | 71 | /** second-level init */ 72 | bool JuliaPostInit(); 73 | 74 | /** reads source file; for julia this uses `import` */ 75 | bool ReadSourceFile(const std::string &file, bool notify = false); 76 | 77 | bool Callback(const BERTBuffers::CallResponse &call, BERTBuffers::CallResponse &response); 78 | 79 | /** 80 | * send message to the console. in julia, stdio is handled separately. console 81 | * messages are used for notifications and non-text output (e.g. images) 82 | */ 83 | void PushConsoleMessage(google::protobuf::Message &message); 84 | -------------------------------------------------------------------------------- /ControlJulia-0.7/lib-0.6.2/libjulia.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia-0.7/lib-0.6.2/libjulia.exp -------------------------------------------------------------------------------- /ControlJulia-0.7/lib-0.6.2/libjulia.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia-0.7/lib-0.6.2/libjulia.lib -------------------------------------------------------------------------------- /ControlJulia-0.7/lib-0.7.0/libjulia.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia-0.7/lib-0.7.0/libjulia.exp -------------------------------------------------------------------------------- /ControlJulia-0.7/lib-0.7.0/libjulia.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia-0.7/lib-0.7.0/libjulia.lib -------------------------------------------------------------------------------- /ControlJulia/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | *.vcxproj.user 3 | -------------------------------------------------------------------------------- /ControlJulia/ControlJulia.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {2cdc21e6-7e2a-4a9f-891e-733c69ebc86c} 18 | 19 | 20 | {f7b2ec5b-4242-4b44-87a6-77b682f4697c} 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | PB 32 | 33 | 34 | Common 35 | 36 | 37 | Common 38 | 39 | 40 | Common 41 | 42 | 43 | Common 44 | 45 | 46 | Common 47 | 48 | 49 | Common 50 | 51 | 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | PB 61 | 62 | 63 | Common 64 | 65 | 66 | Common 67 | 68 | 69 | Common 70 | 71 | 72 | Common 73 | 74 | 75 | -------------------------------------------------------------------------------- /ControlJulia/include/control_julia.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "variable.pb.h" 39 | #include "message_utilities.h" 40 | #include "pipe.h" 41 | #include "process_exit_codes.h" 42 | -------------------------------------------------------------------------------- /ControlJulia/include/julia_interface.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "variable.pb.h" 40 | #include "string_utilities.h" 41 | #include "message_utilities.h" 42 | 43 | typedef enum { 44 | Error = 0, 45 | Success, 46 | Incomplete 47 | } 48 | ExecResult; 49 | 50 | /** startup */ 51 | void JuliaInit(); 52 | 53 | /** shutdown */ 54 | void JuliaShutdown(); 55 | 56 | /** get version so we can gate/limit */ 57 | void JuliaGetVersion(int32_t *major, int32_t *minor, int32_t *patch); 58 | 59 | /** exec in a shell context; as if we're typing at the repl */ 60 | ExecResult JuliaShellExec(const std::string &command, const std::string &shell_buffer); 61 | 62 | /** returns a list of functions exported to excel */ 63 | void ListScriptFunctions(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 64 | 65 | /** runs arbitrary julia code */ 66 | void JuliaExec(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 67 | 68 | /** runs julia function by name, optionally with arguments */ 69 | void JuliaCall(BERTBuffers::CallResponse &response, const BERTBuffers::CallResponse &call); 70 | 71 | /** second-level init */ 72 | bool JuliaPostInit(); 73 | 74 | /** reads source file; for julia this uses `import` */ 75 | bool ReadSourceFile(const std::string &file, bool notify = false); 76 | 77 | bool Callback(const BERTBuffers::CallResponse &call, BERTBuffers::CallResponse &response); 78 | 79 | /** 80 | * send message to the console. in julia, stdio is handled separately. console 81 | * messages are used for notifications and non-text output (e.g. images) 82 | */ 83 | void PushConsoleMessage(google::protobuf::Message &message); 84 | -------------------------------------------------------------------------------- /ControlJulia/lib/libjulia.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia/lib/libjulia.exp -------------------------------------------------------------------------------- /ControlJulia/lib/libjulia.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlJulia/lib/libjulia.lib -------------------------------------------------------------------------------- /ControlR/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | *.vcxproj.user 3 | -------------------------------------------------------------------------------- /ControlR/ControlR.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {eaec0e65-b09a-4f4a-b0cf-36767ab73c6a} 6 | 7 | 8 | {c7527adb-7d4d-47cb-95c8-e837c5f10af9} 9 | 10 | 11 | {c356d784-9c8e-4e2e-ae6f-46120e8ca313} 12 | 13 | 14 | {d7221d55-a44b-4131-952c-de4b56a561f6} 15 | 16 | 17 | 18 | 19 | PB 20 | 21 | 22 | Common 23 | 24 | 25 | Common 26 | 27 | 28 | source 29 | 30 | 31 | source 32 | 33 | 34 | source 35 | 36 | 37 | source 38 | 39 | 40 | source 41 | 42 | 43 | source 44 | 45 | 46 | source 47 | 48 | 49 | Common 50 | 51 | 52 | Common 53 | 54 | 55 | 56 | 57 | PB 58 | 59 | 60 | Common 61 | 62 | 63 | Common 64 | 65 | 66 | Common 67 | 68 | 69 | Common 70 | 71 | 72 | include 73 | 74 | 75 | include 76 | 77 | 78 | include 79 | 80 | 81 | include 82 | 83 | 84 | include 85 | 86 | 87 | include 88 | 89 | 90 | Common 91 | 92 | 93 | Common 94 | 95 | 96 | 97 | 98 | PB 99 | 100 | 101 | -------------------------------------------------------------------------------- /ControlR/include/console_graphics_device.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #ifndef __CONSOLE_GRAPHICS_DEVICE_H 21 | #define __CONSOLE_GRAPHICS_DEVICE_H 22 | 23 | #include 24 | 25 | namespace ConsoleGraphicsDevice { 26 | 27 | SEXP CreateConsoleDevice(const std::string &background, double width, double height, double pointsize, const std::string &type, void * pointer); 28 | 29 | }; 30 | 31 | #endif // #ifndef __CONSOLE_GRAPHICS_DEVICE_H 32 | 33 | -------------------------------------------------------------------------------- /ControlR/include/controlr_common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #ifndef __CONTROLR_COMMON_H 21 | #define __CONTROLR_COMMON_H 22 | 23 | #ifdef WIN32 24 | 25 | #define Win32 26 | #include 27 | 28 | #else // #ifdef WIN32 29 | 30 | #define R_INTERFACE_PTRS 31 | 32 | #endif // #ifdef WIN32 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | #ifdef WIN32 46 | 47 | #include 48 | #include 49 | 50 | #else // #ifdef WIN32 51 | 52 | #include 53 | #include 54 | #include 55 | 56 | #endif // #ifdef WIN32 57 | 58 | #include 59 | #include 60 | 61 | // try to store fuel now, you jerks 62 | #undef clear 63 | #undef length 64 | 65 | SEXP RCallback(SEXP, SEXP); 66 | SEXP COMCallback(SEXP, SEXP, SEXP, SEXP, SEXP); 67 | 68 | extern "C" { 69 | 70 | // loop functions 71 | extern void setup_Rmainloop(); 72 | extern void run_Rmainloop(); 73 | 74 | // in case we want to call these programatically (TODO) 75 | extern void R_RestoreGlobalEnvFromFile(const char *, Rboolean); 76 | extern void R_SaveGlobalEnvToFile(const char *); 77 | 78 | // for win32 79 | extern void R_ProcessEvents(void); 80 | 81 | extern void Rf_PrintWarnings(); 82 | extern Rboolean R_Visible; 83 | 84 | }; 85 | 86 | #endif // #ifndef __CONTROLR_COMMON_H 87 | 88 | 89 | -------------------------------------------------------------------------------- /ControlR/include/convert.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | /** 27 | * thanks to 28 | * http://www.zedwood.com/article/cpp-is-valid-utf8-string-function 29 | */ 30 | bool ValidUTF8(const char *string, int len); 31 | 32 | void WindowsCPToUTF8(const char *input_buffer, int input_length, char **output_buffer, int *output_length); 33 | 34 | std::string WindowsCPToUTF8_2(const char *input_buffer, int input_length); 35 | -------------------------------------------------------------------------------- /ControlR/include/spreadsheet_graphics_device.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #ifndef __SPREADSGEET_GRAPHICS_DEVICE_H 21 | #define __SPREADSGEET_GRAPHICS_DEVICE_H 22 | 23 | #include 24 | #include "gdi_graphics_device.h" 25 | 26 | namespace SpreadsheetGraphicsDevice { 27 | 28 | SEXP CreateSpreadsheetDevice(const std::string &name, const std::string &background, double width, double height, double pointsize, void * pointer); 29 | // std::vector UpdatePendingGraphics(); 30 | std::vector UpdatePendingGraphics(); 31 | 32 | }; 33 | 34 | 35 | 36 | #endif // #ifndef __SPREADSGEET_GRAPHICS_DEVICE_H 37 | 38 | -------------------------------------------------------------------------------- /ControlR/lib/R64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlR/lib/R64.lib -------------------------------------------------------------------------------- /ControlR/lib/RGraphApp64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlR/lib/RGraphApp64.lib -------------------------------------------------------------------------------- /ControlR/lib/RebuildLibs.ps1: -------------------------------------------------------------------------------- 1 | #============================================= 2 | # 3 | # Copyright (c) 2015 Structured Data, LLC. 4 | # All rights reserved. 5 | # 6 | #============================================= 7 | 8 | #============================================= 9 | # parameters 10 | #============================================= 11 | 12 | Param( [switch]$x86, 13 | [switch]$x64, 14 | [switch]$def, 15 | [switch]$all, 16 | [String]$R 17 | ); 18 | 19 | if( $all ) 20 | { 21 | $def = $TRUE; 22 | $x86 = $TRUE; 23 | $x64 = $TRUE; 24 | }; 25 | 26 | #============================================= 27 | # functions 28 | #============================================= 29 | 30 | #--------------------------------------------- 31 | # exit on error, with message 32 | #--------------------------------------------- 33 | Function ExitOnError( $message ) { 34 | 35 | if( $LastExitCode -ne 0 ){ 36 | if( $message -ne $null ){ Write-Host "$message" -foregroundcolor red ; } 37 | Write-Host "Exit on error: $LastExitCode`r`n" -foregroundcolor red ; 38 | Exit $LastExitCode; 39 | } 40 | 41 | } 42 | 43 | #--------------------------------------------- 44 | # create the .def file 45 | #--------------------------------------------- 46 | Function GenerateDef( $sub, $key ) { 47 | 48 | Write-Host "Generating $key-bit .defs (R.dll)" -foregroundcolor yellow ; 49 | 50 | $cmd = "dumpbin /exports $r\bin\$sub\R.dll" 51 | Write-Host "$cmd" 52 | 53 | $symbols = dumpbin /exports $r\bin\$sub\R.dll | Out-String 54 | ExitOnError; 55 | Write-Host "11"; 56 | 57 | $symbols = ($symbols -replace "(?s)^.*ordinal.*?\n", ""); 58 | $symbols = ($symbols -replace "(?s)\n\s*Summary.*?$", ""); 59 | $symbols = ($symbols -replace "(?m)^\s+\S+\s+\S+\s+\S+\s+", ""); 60 | 61 | echo "LIBRARY R`nEXPORTS`n`n$symbols`n" | Out-File -encoding ASCII R$key.def 62 | ExitOnError; 63 | 64 | Write-Host "Generating $key-bit .defs (RGraphApp.dll)" -foregroundcolor yellow ; 65 | 66 | $symbols = dumpbin /exports $r\bin\$sub\RGraphApp.dll | Out-String 67 | ExitOnError; 68 | 69 | $symbols = ($symbols -replace "(?s)^.*ordinal.*?\n", ""); 70 | $symbols = ($symbols -replace "(?s)\n\s*Summary.*?$", ""); 71 | $symbols = ($symbols -replace "(?m)^\s+\S+\s+\S+\s+\S+\s+", ""); 72 | 73 | $symbols = ($symbols -replace "(?m)^\(.*?\n", ""); 74 | 75 | echo "LIBRARY RGraphApp`nEXPORTS`n`n$symbols`n" | Out-File -encoding ASCII RGraphApp$key.def 76 | ExitOnError; 77 | 78 | } 79 | 80 | #--------------------------------------------- 81 | # create the lib file from the .def 82 | #--------------------------------------------- 83 | Function GenerateLib( $machine, $key ){ 84 | 85 | Write-Host "Generating $key-bit libs" -foregroundcolor yellow ; 86 | lib /machine:$machine /def:R$key.def /out:R$key.lib 87 | lib /machine:$machine /def:RGraphApp$key.def /out:RGraphApp$key.lib 88 | ExitOnError; 89 | 90 | } 91 | 92 | #============================================= 93 | # runtime 94 | #============================================= 95 | 96 | Write-Host ""; 97 | if( $def ){ 98 | if( $x86 ){ GenerateDef "i386" "32" } 99 | if( $x64 ){ GenerateDef "x64" "64" } 100 | Write-Host ""; 101 | } 102 | if( $x86 ){ GenerateLib "X86" "32" } 103 | if( $x64 ){ GenerateLib "X64" "64" } 104 | Write-Host ""; 105 | Write-Host "Done" -foregroundcolor green; 106 | Write-Host ""; 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /ControlR/src/controlr.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/ControlR/src/controlr.cc -------------------------------------------------------------------------------- /Examples/excel-scripting.jl: -------------------------------------------------------------------------------- 1 | 2 | #= 3 | 4 | The Excel scripting interface, via COM, is object-oriented. Julia 5 | is not. We decided to map COM onto Julia using objects. For a variety 6 | of reasons this seemed like the better alternative, although it 7 | results in a syntax that seems somewhat unjulian. 8 | 9 | We may revisit this in the future, pending some more real-world 10 | experience. For the time being, here is how to use the Excel 11 | interface. Paste this code into the shell (or right-click the editor 12 | and execute). 13 | 14 | =# 15 | 16 | # 17 | # get the active workbook. create one if it doesn't exist 18 | # (you're on the start screen?) 19 | # 20 | wb = EXCEL.Application.get_ActiveWorkbook() 21 | if( wb == nothing ) 22 | wb = EXCEL.Application.get_Workbooks().Add() 23 | end 24 | 25 | # 26 | # get the worksheets pointer and add a new sheet 27 | # 28 | new_sheet = wb.get_Worksheets().Add() 29 | 30 | # 31 | # change the name. note this will fail if a sheet with this name 32 | # already exists (like if you run this code twice) 33 | # 34 | new_sheet.put_Name("Julia Data") 35 | 36 | # 37 | # create some test data -- here it's a 20x5 array 38 | # 39 | data = reshape(randn(100), (20,5)) 40 | 41 | # 42 | # now insert this into the new sheet 43 | # 44 | new_sheet.get_Range("B2:F21").put_Value(data) 45 | 46 | # 47 | # add some headers. NOTE: transponse does not work on 48 | # strings in julia? seems like an oversight. 49 | # [NB: it's `permutedims`] 50 | # 51 | header_range = new_sheet.get_Range("B1:F1") 52 | header_range.put_Value(hcat("A", "B", "C", "D", "E")) 53 | 54 | # 55 | # example of using constants: add border (underline) 56 | # 57 | border = header_range.get_Borders(EXCEL.XlBordersIndex.xlEdgeBottom) 58 | border.put_Weight( EXCEL.XlBorderWeight.xlThin ) 59 | 60 | # 61 | # center headers 62 | # 63 | header_range.put_HorizontalAlignment(EXCEL.Constants.xlCenter) 64 | 65 | -------------------------------------------------------------------------------- /Examples/excel-scripting.r: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Here's an example of using the Excel scripting interface 4 | # (paste this code into the shell). 5 | # 6 | # For more information, see 7 | # 8 | # https://bert-toolkit.com/excel-scripting-interface-in-r 9 | # 10 | 11 | # 12 | # get a reference to the workbook. create a new one if 13 | # it doesn't exist (you're on the start screen?) 14 | # 15 | wb <- EXCEL$Application$get_ActiveWorkbook(); 16 | if(is.null(wb)){ 17 | wb <- EXCEL$Application$get_Workbooks()$Add(); 18 | } 19 | 20 | # 21 | # add a sheet 22 | # 23 | new.sheet <- wb$get_Sheets()$Add(); 24 | 25 | # 26 | # change the name of the new sheet. note that this will 27 | # fail if a sheet with this name already exists. 28 | # 29 | new.sheet$put_Name( "R Data Set" ); 30 | 31 | # 32 | # add some data. includes headers 33 | # 34 | range <- new.sheet$get_Range( "B2:F152" ); 35 | range$put_Value( iris ); 36 | 37 | # 38 | # add column headers 39 | # 40 | header.range <- new.sheet$get_Range( "B2:F2" ); 41 | #header.range$put_Value( t( colnames( iris ))); 42 | 43 | # 44 | # resize columns to fit 45 | # 46 | range$get_EntireColumn()$AutoFit(); 47 | 48 | # 49 | # example of using constants: add border (underline) to headers 50 | # 51 | border <- header.range$get_Borders(EXCEL$XlBordersIndex$xlEdgeBottom); 52 | border$put_Weight( EXCEL$XlBorderWeight$xlThin ); 53 | 54 | # 55 | # center headers 56 | # 57 | header.range$put_HorizontalAlignment(EXCEL$Constants$xlCenter); 58 | 59 | -------------------------------------------------------------------------------- /Examples/functions.jl: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | add all arguments. flatten ranges (arrays) 4 | 5 | """ 6 | function TestAdd(a...) 7 | sum(collect(Base.Iterators.flatten(a))) 8 | end 9 | 10 | """ 11 | eigenvalues for matrix. returns vector 12 | 13 | """ 14 | function EigenValues(mat) 15 | eigvals(mat) 16 | end 17 | 18 | -------------------------------------------------------------------------------- /Examples/functions.r: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # add all arguments 4 | # 5 | TestAdd <- function(...){ 6 | sum(...) 7 | } 8 | 9 | # 10 | # eigenvalues for matrix (returns a vector) 11 | # 12 | EigenValues <- function(mat){ 13 | eigen(mat)$values 14 | } 15 | -------------------------------------------------------------------------------- /Install/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.exe 3 | *.zip 4 | build-log.txt 5 | -------------------------------------------------------------------------------- /Install/README.md: -------------------------------------------------------------------------------- 1 | 2 | Using nsis for initial builds. 3 | 4 | -------------------------------------------------------------------------------- /Install/bert2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Install/bert2.ico -------------------------------------------------------------------------------- /Module/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | src-x64 3 | src-i386 4 | README-LOCAL.md 5 | -------------------------------------------------------------------------------- /Module/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: BERTModule 2 | Type: Package 3 | Title: Utilities for BERT 4 | Version: 2.0.14 5 | Date: 2018-02-18 6 | Author: Duncan Werner 7 | Maintainer: Duncan Werner 8 | Description: Utilities for BERT 9 | License: GPL (>= 3) 10 | RoxygenNote: 6.0.1 11 | -------------------------------------------------------------------------------- /Module/NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(close,js.client.progress.bar) 4 | S3method(print,ordered.history) 5 | export(BERT.console.graphics.device) 6 | export(BERT.graphics.device) 7 | export(ncol) 8 | export(nrow) 9 | export(pad.excel.array) 10 | export(range.to.data.frame) 11 | useDynLib(BERTModule) 12 | -------------------------------------------------------------------------------- /Module/README.md: -------------------------------------------------------------------------------- 1 | 2 | BERTModule 3 | ========== 4 | 5 | Support functions for [BERT][1]. 6 | 7 | Overview 8 | -------- 9 | 10 | This module is part of BERT, and probably not useful on its own. 11 | 12 | Some BERT functionality (primarily R, but some C++ as well) is 13 | moving out of the core and into a separate module. This is 14 | happening for two reasons: (1) proper namespacing; (2) proper 15 | documentation for functions; and (3) the graphics device. 16 | 17 | Regarding the last one, building the module allows better interfacing 18 | with R as BERT is built using MSVC while R on Windows is (usually) 19 | built with [mingw][3]. 20 | 21 | License 22 | ------- 23 | 24 | [GPL v2][2]. Copyright (c) 2017 Structured Data, LLC. 25 | 26 | Build and install 27 | ----------------- 28 | 29 | Set appropriate environment variables (see generally docs on 30 | building modules; you will need Windows R build tools installed). 31 | To generate package and documentation files, 32 | 33 | ``` 34 | > R -e "library(roxygen2); roxygenise('BERTModule');" 35 | ``` 36 | 37 | Build with 38 | 39 | ``` 40 | > R CMD build BERTModule && R CMD INSTALL BERTModule 41 | ``` 42 | 43 | [1]: https://bert-toolkit.com 44 | [2]: https://opensource.org/licenses/gpl-2.0.php 45 | [3]: http://www.mingw.org/ 46 | 47 | -------------------------------------------------------------------------------- /Module/man/BERT.console.graphics.device.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{BERT.console.graphics.device} 4 | \alias{BERT.console.graphics.device} 5 | \title{Create a console graphics device.} 6 | \usage{ 7 | BERT.console.graphics.device(bgcolor = "white", width = 500, height = 350, 8 | pointsize = 14, type = "png") 9 | } 10 | \description{ 11 | \code{BERT.console.graphics.device} creates a graphics device that 12 | renders to the shell. type is either "svg" or "png". 13 | } 14 | -------------------------------------------------------------------------------- /Module/man/BERT.graphics.device.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{BERT.graphics.device} 4 | \alias{BERT.graphics.device} 5 | \title{Create a BERT graphics device.} 6 | \usage{ 7 | BERT.graphics.device(name = "BERT-default", bgcolor = "white", 8 | width = 400, height = 400, pointsize = 12, 9 | scale = Sys.getenv("BERTGraphicsScale"), cell = F) 10 | } 11 | \description{ 12 | \code{BERT.graphics.device} creates a graphics device that renders to 13 | a named Shape in an Excel workbook. 14 | } 15 | \details{ 16 | If this is called from an Excel spreadsheet cell, set \code{cell=TRUE} 17 | and it will use a name that's generated from the cell address, which 18 | should be unique in the workbook. (That won't survive sheet renaming, 19 | but in that case just toss the old one and a new one will be generated 20 | on the next paint). 21 | 22 | Size, background and pointsize arguments are ignored if the target 23 | named shape already exists. The values for these arguments are 24 | scaled based on reported screen DPI to give reasonable values on 25 | normal and high-DPI displays (to prevent this behavior, set the scale 26 | parameter to 1). 27 | } 28 | -------------------------------------------------------------------------------- /Module/man/close.js.client.progress.bar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{close.js.client.progress.bar} 4 | \alias{close.js.client.progress.bar} 5 | \title{Generic method for BERT shell progress bar} 6 | \usage{ 7 | \method{close}{js.client.progress.bar}(pb) 8 | } 9 | \description{ 10 | Generic method for BERT shell progress bar 11 | } 12 | -------------------------------------------------------------------------------- /Module/man/history.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{history} 4 | \alias{history} 5 | \title{History implementation for the BERT console} 6 | \usage{ 7 | history(max.show = 25, reverse = FALSE, pattern, ...) 8 | } 9 | \description{ 10 | History implementation for the BERT console 11 | } 12 | -------------------------------------------------------------------------------- /Module/man/pad.excel.array.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{pad.excel.array} 4 | \alias{pad.excel.array} 5 | \title{pad an excel array with empty strings} 6 | \usage{ 7 | pad.excel.array(rslt) 8 | } 9 | \description{ 10 | if you enter an R function in an Excel array, but the function result 11 | is smaller than the Excel range, the range will be filled with #N/A errors. 12 | this is the correct behavior, but it can be unattractive. this function 13 | will check the size of the output range, and if the data is smaller, will 14 | fill the range with empty strings ("") that render as empty cells in Excel. 15 | } 16 | -------------------------------------------------------------------------------- /Module/man/print.ordered.history.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{print.ordered.history} 4 | \alias{print.ordered.history} 5 | \title{Print console history} 6 | \usage{ 7 | \method{print}{ordered.history}(h) 8 | } 9 | \description{ 10 | Print console history 11 | } 12 | -------------------------------------------------------------------------------- /Module/man/range.to.data.frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BERTModule.R 3 | \name{range.to.data.frame} 4 | \alias{range.to.data.frame} 5 | \title{Convert a list of lists into a data frame} 6 | \usage{ 7 | \method{range}{to.data.frame}(rng, headers = FALSE, 8 | stringsAsFactors = default.stringsAsFactors()) 9 | } 10 | \description{ 11 | Spreadsheet functions that accept a range as an argument and range values 12 | returned by the COM/scripting API may be returned as list-of-list 13 | structures. BERT does that to preserve type information; R vectors can't 14 | contain mixed types. This function will convert a list-of-lists structure 15 | into a data frame, optionally with column headers. 16 | } 17 | -------------------------------------------------------------------------------- /PB/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PROTOC=../../protoc-3.5.0-win32/bin/protoc.exe 4 | 5 | $PROTOC --cpp_out=. variable.proto 6 | $PROTOC --js_out=import_style=commonjs,binary:../Console/generated/ variable.proto 7 | 8 | -------------------------------------------------------------------------------- /Ribbon/.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | Win32 3 | .vs 4 | 5 | *.exp 6 | *.lib 7 | *.pdb 8 | *.ilk 9 | *.iobj 10 | *.ipdb 11 | *.aps 12 | 13 | *.vcxproj.user 14 | 15 | *.exe 16 | *.xll 17 | *.dll 18 | 19 | # these are generated, but it's kind of a simple 20 | # pattern. we might want to exclude by name just 21 | # in case. 22 | 23 | *_i.c 24 | *_i.h 25 | 26 | 27 | -------------------------------------------------------------------------------- /Ribbon/BERTRibbon2.idl: -------------------------------------------------------------------------------- 1 | // BERTRibbon2.idl : IDL source for BERTRibbon2 2 | // 3 | 4 | // This file will be processed by the MIDL tool to 5 | // produce the type library (BERTRibbon2.tlb) and marshalling code. 6 | 7 | import "oaidl.idl"; 8 | import "ocidl.idl"; 9 | 10 | [ 11 | uuid(443a0014-c3f3-4ced-a258-f170aff12659), 12 | version(2.0), 13 | helpstring("BERT2 Ribbon Library") 14 | ] 15 | library BERT2RibbonLib 16 | { 17 | importlib("stdole2.tlb"); 18 | [ 19 | uuid(1451f06e-b530-4289-8d1f-7ea4a79f7732), 20 | helpstring("BERT2 Ribbon") 21 | ] 22 | coclass Connect 23 | { 24 | [default] interface IUnknown; 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /Ribbon/BERTRibbon2.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Ribbon/BERTRibbon2.rc -------------------------------------------------------------------------------- /Ribbon/BERTRibbon2.rgs: -------------------------------------------------------------------------------- 1 | HKCU 2 | { 3 | Software 4 | { 5 | Classes 6 | { 7 | BERT2Ribbon.Connect.1 = s 'BERT2 Ribbon Menu Class' 8 | { 9 | CLSID = s '{1451f06e-b530-4289-8d1f-7ea4a79f7732}' 10 | } 11 | BERT2Ribbon.Connect = s 'BERT2 Ribbon Menu Class' 12 | { 13 | CLSID = s '{1451f06e-b530-4289-8d1f-7ea4a79f7732}' 14 | CurVer = s 'BERT2Ribbon.Connect.1' 15 | } 16 | NoRemove CLSID 17 | { 18 | ForceRemove '{1451f06e-b530-4289-8d1f-7ea4a79f7732}' = s 'BERT2 Ribbon Menu Class' 19 | { 20 | ProgID = s 'BERT2Ribbon.Connect.1' 21 | VersionIndependentProgID = s 'BERT2Ribbon.Connect' 22 | ForceRemove 'Programmable' 23 | InprocServer32 = s '%MODULE%' 24 | { 25 | val ThreadingModel = s 'Apartment' 26 | } 27 | 'TypeLib' = s '{443a0014-c3f3-4ced-a258-f170aff12659}' 28 | } 29 | } 30 | } 31 | Microsoft 32 | { 33 | Office 34 | { 35 | Excel 36 | { 37 | NoRemove Addins 38 | { 39 | ForceRemove BERT2Ribbon.Connect 40 | { 41 | val Description = s 'BERT2 Ribbon Menu Class' 42 | val FriendlyName = s 'BERT2 Ribbon Menu' 43 | val LoadBehavior = d 3 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /Ribbon/BERTRibbon2.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | sources 6 | 7 | 8 | sources 9 | 10 | 11 | sources 12 | 13 | 14 | sources 15 | 16 | 17 | 18 | 19 | includes 20 | 21 | 22 | includes 23 | 24 | 25 | includes 26 | 27 | 28 | includes 29 | 30 | 31 | common 32 | 33 | 34 | 35 | 36 | sources 37 | 38 | 39 | sources 40 | 41 | 42 | 43 | 44 | {9e49db10-9f75-486c-ac84-04bec76418e5} 45 | 46 | 47 | {b56aa032-fd8e-4f8b-b70a-b3d5e5fa413f} 48 | 49 | 50 | {94ac2df8-10d8-41d0-943f-dae108c7f6a0} 51 | 52 | 53 | {debf9a20-ce85-4f8f-bddf-087cd2805028} 54 | 55 | 56 | 57 | 58 | sources 59 | 60 | 61 | 62 | 63 | resources 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Ribbon/Ribbon.def: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright (c) 2017-2018 Structured Data, LLC 3 | ; 4 | ; This file is part of BERT. 5 | ; 6 | ; BERT is free software: you can redistribute it and/or modify 7 | ; it under the terms of the GNU General Public License as published by 8 | ; the Free Software Foundation, either version 3 of the License, or 9 | ; (at your option) any later version. 10 | ; 11 | ; BERT is distributed in the hope that it will be useful, 12 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ; GNU General Public License for more details. 15 | ; 16 | ; You should have received a copy of the GNU General Public License 17 | ; along with BERT. If not, see . 18 | ; 19 | 20 | LIBRARY 21 | 22 | EXPORTS 23 | DllCanUnloadNow PRIVATE 24 | DllGetClassObject PRIVATE 25 | DllRegisterServer PRIVATE 26 | DllUnregisterServer PRIVATE 27 | DllInstall PRIVATE 28 | 29 | -------------------------------------------------------------------------------- /Ribbon/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "stdafx.h" 21 | #include "resource.h" 22 | #include "BERTRibbon2_i.h" 23 | 24 | CBERT2RibbonModule _AtlModule; 25 | 26 | // DLL Entry Point 27 | extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 28 | { 29 | 30 | #ifdef _MERGE_PROXYSTUB 31 | if (!PrxDllMain(hInstance, dwReason, lpReserved)) 32 | return FALSE; 33 | #endif 34 | hInstance; 35 | return _AtlModule.DllMain(dwReason, lpReserved); 36 | } 37 | -------------------------------------------------------------------------------- /Ribbon/images/console-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Ribbon/images/console-16.png -------------------------------------------------------------------------------- /Ribbon/images/console-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Ribbon/images/console-32.png -------------------------------------------------------------------------------- /Ribbon/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdllc/Basic-Excel-R-Toolkit/15293c95c25ca874cf8a44206a2edaec1ea330a4/Ribbon/resource.h -------------------------------------------------------------------------------- /Ribbon/ribbon.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "stdafx.h" 21 | #include "resource.h" 22 | #include "BERTRibbon2_i.h" 23 | 24 | using namespace ATL; 25 | 26 | // Used to determine whether the DLL can be unloaded by OLE. 27 | STDAPI DllCanUnloadNow(void) 28 | { 29 | #ifdef _MERGE_PROXYSTUB 30 | HRESULT hr = PrxDllCanUnloadNow(); 31 | if (hr != S_OK) 32 | return hr; 33 | #endif 34 | return _AtlModule.DllCanUnloadNow(); 35 | } 36 | 37 | // Returns a class factory to create an object of the requested type. 38 | STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv) 39 | { 40 | #ifdef _MERGE_PROXYSTUB 41 | HRESULT hr = PrxDllGetClassObject(rclsid, riid, ppv); 42 | if (hr != CLASS_E_CLASSNOTAVAILABLE) 43 | return hr; 44 | #endif 45 | return _AtlModule.DllGetClassObject(rclsid, riid, ppv); 46 | } 47 | 48 | // DllRegisterServer - Adds entries to the system registry. 49 | STDAPI DllRegisterServer(void) 50 | { 51 | // registers object, typelib and all interfaces in typelib 52 | HRESULT hr = _AtlModule.DllRegisterServer(); 53 | #ifdef _MERGE_PROXYSTUB 54 | if (FAILED(hr)) 55 | return hr; 56 | hr = PrxDllRegisterServer(); 57 | #endif 58 | return hr; 59 | } 60 | 61 | // DllUnregisterServer - Removes entries from the system registry. 62 | STDAPI DllUnregisterServer(void) 63 | { 64 | HRESULT hr = _AtlModule.DllUnregisterServer(); 65 | #ifdef _MERGE_PROXYSTUB 66 | if (FAILED(hr)) 67 | return hr; 68 | hr = PrxDllRegisterServer(); 69 | if (FAILED(hr)) 70 | return hr; 71 | hr = PrxDllUnregisterServer(); 72 | #endif 73 | return hr; 74 | } 75 | 76 | // DllInstall - Adds/Removes entries to the system registry per user per machine. 77 | STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine) 78 | { 79 | HRESULT hr = E_FAIL; 80 | static const wchar_t szUserSwitch[] = L"user"; 81 | 82 | if (pszCmdLine != NULL) 83 | { 84 | if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0) 85 | { 86 | ATL::AtlSetPerUserRegistration(true); 87 | } 88 | } 89 | 90 | if (bInstall) 91 | { 92 | hr = DllRegisterServer(); 93 | if (FAILED(hr)) 94 | { 95 | DllUnregisterServer(); 96 | } 97 | } 98 | else 99 | { 100 | hr = DllUnregisterServer(); 101 | } 102 | 103 | return hr; 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /Ribbon/stdafx.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #include "stdafx.h" 21 | -------------------------------------------------------------------------------- /Ribbon/stdafx.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-2018 Structured Data, LLC 3 | * 4 | * This file is part of BERT. 5 | * 6 | * BERT is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BERT is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with BERT. If not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #ifndef STRICT 23 | #define STRICT 24 | #endif 25 | 26 | // Modify the following defines if you have to target a platform prior to the ones specified below. 27 | // Refer to MSDN for the latest info on corresponding values for different platforms. 28 | #ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. 29 | #define WINVER 0x0600 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. 30 | #endif 31 | 32 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. 33 | //#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. 34 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target Windows 2000 or later. 35 | #endif 36 | 37 | #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. 38 | //#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. 39 | #define _WIN32_WINDOWS 0x0600// Change this to the appropriate value to target Windows Me or later. 40 | #endif 41 | 42 | #ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. 43 | #define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. 44 | #endif 45 | 46 | #define _ATL_APARTMENT_THREADED 47 | #define _ATL_NO_AUTOMATIC_NAMESPACE 48 | 49 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 50 | 51 | // turns off ATL's hiding of some common and often safely ignored warning messages 52 | #define _ATL_ALL_WARNINGS 53 | 54 | 55 | #include "resource.h" 56 | #include 57 | #include 58 | #include 59 | 60 | #include 61 | #include 62 | 63 | #pragma warning( disable : 4278 ) 64 | #pragma warning( disable : 4146 ) 65 | //The following #import imports the IDTExtensibility2 interface based on it's LIBID 66 | #import "libid:AC0714F2-3D04-11D1-AE7D-00A0C90F26F4" version("1.0") lcid("0") raw_interfaces_only named_guids 67 | 68 | #pragma warning( default : 4146 ) 69 | #pragma warning( default : 4278 ) 70 | 71 | #define IfFailGo(x) { hr=(x); if (FAILED(hr)) goto Error; } 72 | #define IfFailGoCheck(x, p) { hr=(x); if (FAILED(hr)) goto Error; if(!p) {hr = E_FAIL; goto Error; } } 73 | 74 | class DECLSPEC_UUID("443a0014-c3f3-4ced-a258-f170aff12659") BERT2RibbonLib; 75 | 76 | using namespace ATL; 77 | 78 | class CBERT2RibbonModule : public CAtlDllModuleT< CBERT2RibbonModule > 79 | { 80 | public: 81 | CBERT2RibbonModule() 82 | { 83 | m_hInstance = NULL; 84 | } 85 | 86 | DECLARE_LIBID(__uuidof(BERT2RibbonLib)) 87 | 88 | inline HINSTANCE GetResourceInstance() 89 | { 90 | return m_hInstance; 91 | } 92 | 93 | inline void SetResourceInstance(HINSTANCE hInstance) 94 | { 95 | m_hInstance = hInstance; 96 | } 97 | 98 | private: 99 | HINSTANCE m_hInstance; 100 | }; 101 | 102 | extern CBERT2RibbonModule _AtlModule; 103 | 104 | // @see BERTCOM.cpp about these files 105 | 106 | #include "..\OfficeTypes\mso-15.tlh" 107 | using namespace Office; 108 | 109 | #include "..\OfficeTypes\excel-15.tlh" 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Ribbon/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /bert2-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 9 | 10 | 12 | 13 | 14 | 20 | 22 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /logo-transparent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 12 | 14 | 15 | 16 | 22 | 24 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------