diff --git a/markdown/src/main/java/com/nflabs/zeppelin/markdown/Markdown.java b/markdown/src/main/java/com/nflabs/zeppelin/markdown/Markdown.java index 35a6e903..0d652df6 100644 --- a/markdown/src/main/java/com/nflabs/zeppelin/markdown/Markdown.java +++ b/markdown/src/main/java/com/nflabs/zeppelin/markdown/Markdown.java @@ -49,9 +49,7 @@ public InterpreterResult interpret(String st, InterpreterContext interpreterCont String html; try { html = md.process(st); - } catch (IOException e) { - return new InterpreterResult(Code.ERROR, e.getMessage()); - } catch (java.lang.RuntimeException e) { + } catch (IOException | java.lang.RuntimeException e) { return new InterpreterResult(Code.ERROR, e.getMessage()); } return new InterpreterResult(Code.SUCCESS, "%html " + html); diff --git a/zeppelin-web/Gruntfile.js b/zeppelin-web/Gruntfile.js index 064f8546..dfb2c389 100644 --- a/zeppelin-web/Gruntfile.js +++ b/zeppelin-web/Gruntfile.js @@ -58,6 +58,7 @@ module.exports = function (grunt) { files: [ '<%= yeoman.app %>/{,*/}*.html', '.tmp/styles/{,*/}*.css', + '.tmp/styles_noncocat/{,*/}*.css', '<%= yeoman.app %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' ] } @@ -167,6 +168,7 @@ module.exports = function (grunt) { }, app: { src: ['<%= yeoman.app %>/index.html'], + exclude: [ 'bower_components/highlightjs/styles/default.css' ], ignorePath: /\.\.\// } }, @@ -215,15 +217,19 @@ module.exports = function (grunt) { // By default, your `index.html`'s will take care of // minification. These next options are pre-configured if you do not wish // to use the Usemin blocks. - // cssmin: { - // dist: { - // files: { - // '<%= yeoman.dist %>/styles/main.css': [ - // '.tmp/styles/{,*/}*.css' - // ] - // } - // } - // }, + + // Explicit processing for special css directories + cssmin: { + dist: { + files: [{ + expand: true, + dot: true, + cwd: '.tmp/styles_nonconcat/', + dest: '<%= yeoman.dist %>', + src: 'styles/{,*/}*.css' + }] + } + }, // uglify: { // dist: { // files: { @@ -302,7 +308,7 @@ module.exports = function (grunt) { expand : true, dot : true, cwd: '<%= yeoman.app %>', - dest: '<%= yeoman.dist %>', + dest: '.tmp/styles_nonconcat/', src: ['styles/looknfeel/*'] }, { expand: true, @@ -319,6 +325,16 @@ module.exports = function (grunt) { cwd: 'bower_components/jquery-ui/themes/base/images', src: '{,*/}*.{png,jpg,jpeg,gif}', dest: '<%= yeoman.dist %>/styles/images' + }, { + expand: true, + cwd: 'bower_components/highlightjs/styles', + src: '{,*/}*.css', + dest: '.tmp/styles_nonconcat/styles/highlightjs' + }, { + expand: true, + cwd: 'bower_components/highlightjs/styles', + src: '{,*/}*.{png,jpg,jpeg,gif}', + dest: '<%= yeoman.dist %>/styles/highlightjs' }] }, styles: { diff --git a/zeppelin-web/app/index.html b/zeppelin-web/app/index.html index ab4bfc85..96ea3673 100644 --- a/zeppelin-web/app/index.html +++ b/zeppelin-web/app/index.html @@ -48,7 +48,55 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/zeppelin-web/app/scripts/controllers/main.js b/zeppelin-web/app/scripts/controllers/main.js index 34c58084..c8a9a695 100644 --- a/zeppelin-web/app/scripts/controllers/main.js +++ b/zeppelin-web/app/scripts/controllers/main.js @@ -29,6 +29,7 @@ angular.module('zeppelinWebApp') $scope.WebSocketWaitingList = []; $scope.connected = false; $scope.looknfeel = 'default'; + $scope.codeHighlightStyle = 'GitHub'; var init = function() { $scope.asIframe = (($window.location.href.indexOf('asIframe') > -1) ? true : false); @@ -111,4 +112,10 @@ angular.module('zeppelinWebApp') } }); + $rootScope.$on('changeCodeHighlightStyle', function(event, data) { + if (!event.defaultPrevented && data && data !== '') { + $scope.codeHighlightStyle = data; + event.preventDefault(); + } + }); }); diff --git a/zeppelin-web/app/scripts/controllers/notebook.js b/zeppelin-web/app/scripts/controllers/notebook.js index 971e1bc9..2e8d6193 100644 --- a/zeppelin-web/app/scripts/controllers/notebook.js +++ b/zeppelin-web/app/scripts/controllers/notebook.js @@ -58,6 +58,14 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro return value; }; + var getCodeHighlightStyles = function() { + var allStyles = jQuery.makeArray($('link[title]')); + return jQuery.map( allStyles, function(style, index) { + return style.title; + }); + }; + $scope.codeHighlightStyles = getCodeHighlightStyles(); + /** Init the new controller */ var initNotebook = function() { $rootScope.$emit('sendNewEvent', {op: 'GET_NOTE', data: {id: $routeParams.noteId}}); @@ -65,7 +73,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro initNotebook(); - /** Remove the note and go back tot he main page */ + /** Remove the note and go back to the main page */ /** TODO(anthony): In the nearly future, go back to the main page and telle to the dude that the note have been remove */ $scope.removeNote = function(noteId) { var result = confirm('Do you want to delete this notebook?'); @@ -135,6 +143,18 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $rootScope.$emit('setLookAndFeel', $scope.note.config.looknfeel); }; + $scope.changeCodeHighlightStyle = function(style) { + if(style) { + $scope.note.config.codeHighlightStyle = style; + $scope.setConfig(); + $rootScope.$emit('changeCodeHighlightStyle', $scope.note.config.codeHighlightStyle); + + $('link[title]').each(function(i, link) { + link.disabled = (link.title !== style); + }); + } + }; + /** Set cron expression for this note **/ $scope.setCronScheduler = function(cronExpr) { $scope.note.config.cron = cronExpr; @@ -174,9 +194,12 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro } /** set look n feel */ - var looknfeel = note.config.looknfeel + var looknfeel = note.config.looknfeel; $scope.viewOnly = looknfeel == 'report'; $rootScope.$emit('setLookAndFeel', looknfeel); + + var style = note.config.codeHighlightStyle; + $rootScope.$emit('changeCodeHighlightStyle', style); }); var initialize = function() { @@ -184,6 +207,14 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $scope.note.config.looknfeel = 'default'; } + if (!$scope.note.config.codeHighlightStyle) { + $scope.note.config.codeHighlightStyle = 'GitHub'; + } + + $('link[title]').each(function(i, link) { + link.disabled = (link.title !== $scope.note.config.codeHighlightStyle); + }); + // open interpreter binding setting when there're none selected getInterpreterBindings(function(){ var selected = false; @@ -397,6 +428,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $scope.openSetting = function() { $scope.showSetting = true; + $scope.note.config.codeHighlightStyleOrig = $scope.note.config.codeHighlightStyle; getInterpreterBindings(); }; @@ -407,6 +439,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro return; } } + $scope.changeCodeHighlightStyle($scope.note.config.codeHighlightStyleOrig); $scope.showSetting = false; }; @@ -439,7 +472,8 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro }; var isSettingDirty = function() { - if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) { + if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig) && + $scope.note.config.codeHighlightStyle === $scope.note.config.codeHighlightStyleOrig) { return false; } else { return true; diff --git a/zeppelin-web/app/scripts/controllers/paragraph.js b/zeppelin-web/app/scripts/controllers/paragraph.js index 5bc61867..a633f9b5 100644 --- a/zeppelin-web/app/scripts/controllers/paragraph.js +++ b/zeppelin-web/app/scripts/controllers/paragraph.js @@ -210,6 +210,15 @@ angular.module('zeppelinWebApp') } else if (newType === 'HTML') { $scope.renderHtml(); } + + var code = $scope.dirtyText; + if ( code && code.startsWith('%sql')) { + $scope.editor.getSession().setMode(editorMode.sql); + } else if ( code.startsWith('%md')) { + $scope.editor.getSession().setMode(editorMode.markdown); + } else { + $scope.editor.getSession().setMode(editorMode.scala); + } } }); @@ -530,6 +539,7 @@ angular.module('zeppelinWebApp') $('#' + id).height(height.toString() + 'px'); }; + $scope.getEditorValue = function() { return $scope.editor.getValue(); }; diff --git a/zeppelin-web/bower.json b/zeppelin-web/bower.json index 86c2f03a..9f9851f2 100644 --- a/zeppelin-web/bower.json +++ b/zeppelin-web/bower.json @@ -21,7 +21,8 @@ "perfect-scrollbar": "~0.5.4", "ng-sortable": "~1.1.9", "angular-elastic": "~2.4.2", - "angular-elastic-input": "~2.0.1" + "angular-elastic-input": "~2.0.1", + "highlightjs": "~8.4.0" }, "devDependencies": { "angular-mocks": "1.3.8",