Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2016-02-25 13:19:41 +01:00
25 changed files with 403 additions and 313 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ package com.intellij.openapi.roots.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
import com.intellij.openapi.module.ModifiableModuleModel;
@@ -46,8 +45,6 @@ import java.util.*;
@PlatformTestCase.WrapInCommand
public class DirectoryIndexTest extends IdeaTestCase {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest");
private DirectoryIndexImpl myIndex;
private Module myModule2, myModule3;
@@ -460,7 +457,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testModuleSourceAsLibrarySource() throws Exception {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.<String>emptyList(), Arrays.asList(mySrcDir1.getUrl()));
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.emptyList(), Collections.singletonList(mySrcDir1.getUrl()));
checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
Collection<OrderEntry> entriesResult = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
@@ -477,7 +474,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testModuleSourceAsLibraryClasses() throws Exception {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.<String>emptyList());
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.singletonList(mySrcDir1.getUrl()), Collections.emptyList());
checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
assertInstanceOf(assertOneElement(toArray(myIndex.getOrderEntries(assertInProject(mySrcDir1)))), ModuleSourceOrderEntry.class);
}
@@ -699,6 +696,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
ContentEntry contentEntry = PsiTestUtil.addContentRoot(myModule, fileRoot);
assertNotNull(contentEntry);
assertEquals(fileRoot, contentEntry.getFile());
checkInfo(fileRoot, myModule, false, false, "", null);
assertTrue(myFileIndex.isInContent(fileRoot));
@@ -730,12 +728,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertNotInProject(fileRoot);
assertFalse(myFileIndex.isInContent(fileRoot));
assertFalse(myFileIndex.isInSource(fileRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Collections.singletonList(fileRoot));
}
private void assertIteratedContent(ProjectFileIndex fileIndex,
@Nullable List<VirtualFile> contains,
@Nullable List<VirtualFile> doesntContain) {
private static void assertIteratedContent(ProjectFileIndex fileIndex,
@Nullable List<VirtualFile> contains,
@Nullable List<VirtualFile> doesntContain) {
final Set<VirtualFile> collected = new THashSet<VirtualFile>();
fileIndex.iterateContent(new ContentIterator() {
@Override
@@ -768,7 +766,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile fileExcludeRoot = createChildData(mySrcDir1, "fileExcludeRoot.txt");
assertTrue(myFileIndex.isInContent(fileExcludeRoot));
assertTrue(myFileIndex.isInSource(fileExcludeRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
assertIteratedContent(myFileIndex, Collections.singletonList(fileExcludeRoot), null);
PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
assertFalse(myFileIndex.isInContent(fileExcludeRoot));
@@ -778,13 +776,13 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertNull(myFileIndex.getModuleForFile(fileExcludeRoot));
assertEquals(myModule, myFileIndex.getModuleForFile(fileExcludeRoot, false));
assertExcluded(fileExcludeRoot, myModule);
assertIteratedContent(myFileIndex, null, Arrays.asList(fileExcludeRoot));
assertIteratedContent(myFileIndex, null, Collections.singletonList(fileExcludeRoot));
// removing file exclude root
PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
assertTrue(myFileIndex.isInContent(fileExcludeRoot));
assertTrue(myFileIndex.isInSource(fileExcludeRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
assertIteratedContent(myFileIndex, Collections.singletonList(fileExcludeRoot), null);
}
public void testFileModuleExcludeRootUnderFileRoot() throws IOException {
@@ -792,25 +790,25 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.addContentRoot(myModule, fileRoot);
checkInfo(fileRoot, myModule, false, false, "", null);
assertTrue(myFileIndex.isInContent(fileRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
assertIteratedContent(myFileIndex, Collections.singletonList(fileRoot), null);
PsiTestUtil.addExcludedRoot(myModule, fileRoot);
assertFalse(myFileIndex.isInContent(fileRoot));
assertExcluded(fileRoot, myModule);
assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot));
assertIteratedContent(myFileIndex, null, Collections.singletonList(fileRoot));
// removing file exclude root
PsiTestUtil.removeExcludedRoot(myModule, fileRoot);
checkInfo(fileRoot, myModule, false, false, "", null);
assertTrue(myFileIndex.isInContent(fileRoot));
assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
assertIteratedContent(myFileIndex, Collections.singletonList(fileRoot), null);
}
public void testFileLibraryInsideFolderLibrary() throws IOException {
VirtualFile file = createChildData(myLibSrcDir, "empty.txt");
ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib2",
Collections.<String>emptyList(), Collections.singletonList(file.getUrl()),
Collections.<String>emptyList(), DependencyScope.COMPILE, true);
Collections.emptyList(), Collections.singletonList(file.getUrl()),
Collections.emptyList(), DependencyScope.COMPILE, true);
// same for the dir and for the file
checkInfo(file, myModule, false, true, "", null, myModule2, myModule3);
@@ -944,5 +942,4 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);
}
}
}
}
@@ -4,6 +4,9 @@ from pkg_resources import load_entry_point
if __name__ == '__main__':
dist = os.environ.get("PYCHARM_EP_DIST")
name = os.environ.get("PYCHARM_EP_NAME")
sys.exit(
load_entry_point(dist, "console_scripts", name)()
)
if dist == "ipython" and name == "ipython":
from IPython import start_ipython
f = start_ipython
else:
f = load_entry_point(dist, "console_scripts", name)
sys.exit(f())
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -52,6 +52,10 @@
<action class="org.jetbrains.plugins.ipnb.editor.actions.IpnbCodeCellAction" id="IpnbCodeCellAction" text="Code Cell">
<keyboard-shortcut keymap="$default" first-keystroke="ctrl shift s"/>
</action>
<action id="NewIPynbFile" class="org.jetbrains.plugins.ipnb.editor.actions.IpnbCreateFileAction">
<add-to-group group-id="NewGroup" anchor="after" relative-to-action="NewPythonFile"/>
</action>
</actions>
</idea-plugin>
@@ -0,0 +1,34 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -1,4 +0,0 @@
## This is hand-edited. Add all of the non-auto-generated definitions
3A6:varPhi:ALPHA
3C6:varphi:ALPHA
02248:thickapprox:REL
@@ -0,0 +1,28 @@
body {
background-color: #313335 !important;
color: #bababa !important;
}
.MathJax_Display {
color: #bababa !important;
background-color: #313335 !important;
}
#mydiv {
color: #bababa !important;
background-color: #313335 !important;
}
.MathJax {
background-color: #313335 !important;
color: #bababa !important;
}
a {
color: #589df6 !important;
}
.MathJax_Preview {
color: #bababa !important;
}
@@ -1,243 +1,271 @@
package org.jetbrains.plugins.ipnb;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.laf.darcula.DarculaLookAndFeelInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.BrowserHyperlinkListener;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.MarkdownUtil;
import com.intellij.util.ui.UIUtil;
import com.petebevin.markdown.MarkdownProcessor;
import net.sourceforge.jeuclid.MathMLParserSupport;
import net.sourceforge.jeuclid.context.LayoutContextImpl;
import net.sourceforge.jeuclid.context.Parameter;
import net.sourceforge.jeuclid.converter.Converter;
import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
import org.jetbrains.plugins.ipnb.editor.panels.IpnbTexPackageDefinitions;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import uk.ac.ed.ph.snuggletex.SnuggleEngine;
import uk.ac.ed.ph.snuggletex.SnuggleInput;
import uk.ac.ed.ph.snuggletex.SnuggleSession;
import uk.ac.ed.ph.snuggletex.XMLStringOutputOptions;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import javax.swing.*;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.awt.event.MouseWheelEvent;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IpnbUtils {
private static final Logger LOG = Logger.getInstance(IpnbUtils.class);
private static final String ourPrefix = "<html><head><script type=\"text/x-mathjax-config\">\n" +
" MathJax.Hub.Config({\n" +
" tex2jax: {\n" +
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n" +
" displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ],\n" +
" processEscapes: true,\n" +
" processEnvironments: true\n" +
" },\n" +
" displayAlign: 'center',\n" +
" \"HTML-CSS\": {\n" +
" styles: {'#mydiv': {\"font-size\": %s}},\n" +
" preferredFont: null,\n" +
" linebreaks: { automatic: true }\n" +
" }\n" +
" });\n" +
"</script><script type=\"text/javascript\"\n" +
" src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full\">\n" +
" </script></head><body><div id=\"mydiv\">";
private static final String ourPostfix = "</div></body></html>";
private static final MarkdownProcessor ourMarkdownProcessor = new MarkdownProcessor();
private static final String ourImagePrefix = "http://image";
private static final Font ourFont = new Font(Font.SERIF, Font.PLAIN, 16);
private static final String ourBodyRule = "body { font-family: \"DejaVu\"; " +
"font-size: " + ourFont.getSize() + "pt;}";
private static URL ourStyleUrl;
private static final String ourCodeRule = "code { font-family: \"DejaVu\"; " +
"font-size: " + ourFont.getSize() + "pt;}";
public static JComponent createLatexPane(@NotNull final String source, int width) {
final JComponent panel = createHtmlPanel(source, width);
private static final String ourAlertRule = ".alert{ background-color: #fcf8e3;" +
"color: #c09853;" +
"padding: 8px 35px 8px 14px;" +
"border: 1px solid #fbeed5;}";
private static final String ourAlertSuccessRule = ".alert-success{ background-color: #dff0d8;\n" +
"color: #468847;" +
"padding: 8px 35px 8px 14px;" +
"border: 1px solid #d6e9c6;}";
private static final String ourAlertErrorRule = ".alert-error{ background-color: #f2dede;\n" +
"color: #b94a48;" +
"padding: 8px 35px 8px 14px;" +
"border: 1px solid #eed3d7;}";
public static String markdown2Html(@NotNull String description) {
description = StringUtil.replace(description, "class=\"alert alert-success\"", "class=\"alert-success\"");
description = StringUtil.replace(description, "class=\"alert alert-error\"", "class=\"alert-error\"");
ArrayList<String> lines = ContainerUtil.newArrayList(description.split("\n|\r|\r\n"));
MarkdownUtil.replaceHeaders(lines);
return ourMarkdownProcessor.markdown(StringUtil.join(lines, "\n"));
}
public static JEditorPane createLatexPane(@NotNull final String source) {
final JEditorPane editorPane = new JEditorPane();
editorPane.setBackground(IpnbEditorUtil.getBackground());
editorPane.setContentType(new HTMLEditorKit().getContentType());
editorPane.setEditorKit(new HTMLEditorKit());
final HTMLDocument document = (HTMLDocument)editorPane.getDocument();
final StyleSheet sheet = document.getStyleSheet();
sheet.addRule(ourBodyRule);
sheet.addRule(ourCodeRule);
sheet.addRule(ourAlertRule);
sheet.addRule(ourAlertSuccessRule);
sheet.addRule(ourAlertErrorRule);
editorPane.setEditable(false);
final String html = convertToHtml(source, document);
editorPane.setText("<html><body>" + html + "</body></html>");
editorPane.addMouseListener(new MouseAdapter() {
panel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
final Container parent = editorPane.getParent();
final MouseEvent parentEvent = SwingUtilities.convertMouseEvent(editorPane, e, parent);
final Container parent = panel.getParent();
final MouseEvent parentEvent = SwingUtilities.convertMouseEvent(panel, e, parent);
parent.dispatchEvent(parentEvent);
}
});
editorPane.addHyperlinkListener(new BrowserHyperlinkListener());
//TODO: jump to the section (see User Interface#Utilities)
return editorPane;
return panel;
}
public static JComponent createHtmlPanel(@NotNull final String source, int width) {
Platform.setImplicitExit(false);
private static String convertToHtml(@NotNull final String source, @NotNull final HTMLDocument document) {
final JFXPanel javafxPanel = new JFXPanel(){
@Override
protected void processMouseWheelEvent(MouseWheelEvent e) {
final Container parent = getParent();
final MouseEvent parentEvent = SwingUtilities.convertMouseEvent(this, e, parent);
parent.dispatchEvent(parentEvent);
}
};
javafxPanel.setBackground(IpnbEditorUtil.getBackground());
Platform.runLater(() -> {
final WebView webView = new WebView();
webView.setOnDragDetected(new EventHandler<javafx.scene.input.MouseEvent>() {
@Override
public void handle(javafx.scene.input.MouseEvent event) {
}
});
final WebEngine engine = webView.getEngine();
initHyperlinkListener(engine);
engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
public void handle(WebEvent<String> status) {
adjustHeight(webView, javafxPanel, source);
}
});
final String prefix = String.format(ourPrefix, EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize());
engine.loadContent(prefix + convertToHtml(source) + ourPostfix);
final BorderPane pane = new BorderPane(webView);
final Scene scene = new Scene(pane, width != 0 ? width : 20, 20);
javafxPanel.setScene(scene);
Platform.runLater(() -> adjustHeight(webView, javafxPanel, source));
updateLaf(LafManager.getInstance().getCurrentLookAndFeel() instanceof DarculaLookAndFeelInfo,
pane, engine, javafxPanel);
});
return javafxPanel;
}
private static String convertToHtml(@NotNull String source) {
source = StringUtil.replace(source, "class=\"alert alert-success\"", "class=\"alert-success\"");
source = StringUtil.replace(source, "class=\"alert alert-error\"", "class=\"alert-error\"");
ArrayList<String> lines = ContainerUtil.newArrayList(source.split("\n|\r|\r\n"));
MarkdownUtil.replaceHeaders(lines);
source = StringUtil.join(lines, "\n");
final StringBuilder result = new StringBuilder();
StringBuilder markdown = new StringBuilder();
StringBuilder formula = new StringBuilder();
boolean inCode = false;
int inMultiStringCode = 0;
boolean inEnd = false;
source = replaceLinks(source);
source = ourMarkdownProcessor.markdown(source);
boolean escaped = false;
boolean backQuoted = false;
int imageIndex = 0;
for (int i = 0; i != source.length(); ++i) {
final char charAt = source.charAt(i);
if (charAt == '`') {
backQuoted = !backQuoted;
if (source.length() > i + 2 && source.charAt(i + 1) == '`' && source.charAt(i + 2) == '`') {
markdown.append(escaped ? "</code>" : "<code>");
escaped = !escaped;
//noinspection AssignmentToForLoopParameter
i += 2;
continue;
}
}
if (escaped && charAt == '\n') {
markdown.append("<br/>");
continue;
}
if (!escaped && !backQuoted) {
if (charAt == '$' && source.length() > i + 1 && source.charAt(i+1) != '$') {
inCode = !inCode;
}
if (charAt == '\\' && source.substring(i).startsWith("\\begin")) {
inMultiStringCode += 1;
}
if (charAt == '\\' && source.substring(i).startsWith("\\end")) {
inEnd = true;
}
}
final boolean doubleDollar = charAt == '$' && ((source.length() > i + 1 && source.charAt(i + 1) == '$')
|| (i >= 1 && source.charAt(i - 1) == '$'));
if (inCode || inMultiStringCode != 0 || (!backQuoted && doubleDollar)) {
if (markdown.length() != 0) {
result.append(markdown.toString());
markdown = new StringBuilder();
}
formula.append(charAt);
}
else {
if (formula.length() != 0 && charAt == '$') {
formula.append(charAt);
}
else {
markdown.append(charAt);
}
if (formula.length() != 0) {
addFormula(formula.toString(), document, imageIndex, result);
imageIndex += 1;
formula = new StringBuilder();
}
}
if (inEnd && charAt == '}') {
inMultiStringCode -= 1;
inEnd = false;
}
int start = 0;
int end = StringUtil.indexOf(source, "```");
while (end > 0) {
result.append(source.substring(start, end));
result.append(escaped? "</pre>" : "<pre>");
escaped = !escaped;
start = end + 3;
end = StringUtil.indexOf(source, "```", end + 1);
}
if (formula.length() != 0) {
addFormula(formula.toString(), document, imageIndex, result);
}
if (markdown.length() != 0) {
result.append(markdown.toString());
}
return markdown2Html(result.toString());
result.append(source.substring(start));
return result.toString();
}
private static void addFormula(@NotNull final String formulaText, @NotNull final HTMLDocument editorDocument, int imageIndex, StringBuilder result) {
final SnuggleEngine engine = new SnuggleEngine();
engine.getPackages().add(0, IpnbTexPackageDefinitions.getPackage());
@NotNull
private static String replaceLinks(@NotNull String source) {
final Pattern inlineLink = Pattern.compile("(\\[(.*?)\\]\\([ \\t]*<?(.*?)>?[ \\t]*(([\'\"])(.*?)\\5)?\\))", 32);
final Matcher matcher = inlineLink.matcher(source);
final StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String linkText = matcher.group(2);
String url = matcher.group(3);
String title = matcher.group(6);
StringBuilder link = new StringBuilder();
link.append("<a href=\"").append(url).append("\"");
if(title != null) {
link.append(" title=\"");
link.append(title);
link.append("\"");
}
final SnuggleSession session = engine.createSession();
link.append(">").append(linkText);
link.append("</a>");
matcher.appendReplacement(sb, link.toString());
}
matcher.appendTail(sb);
final SnuggleInput input = new SnuggleInput(formulaText);
source = sb.toString();
return source;
}
private static void initHyperlinkListener(@NotNull final WebEngine engine) {
engine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
final EventListener listener = new HyperlinkListener(engine);
addListenerToAllHyperlinkItems(engine, listener);
}
});
}
private static void addListenerToAllHyperlinkItems(WebEngine engine, EventListener listener) {
final Document doc = engine.getDocument();
if (doc != null) {
final NodeList nodeList = doc.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++) {
((EventTarget)nodeList.item(i)).addEventListener("click", listener, false);
}
}
}
private static class HyperlinkListener implements EventListener {
@NotNull private final WebEngine myEngine;
public HyperlinkListener(@NotNull final WebEngine engine) {
myEngine = engine;
}
@Override
public void handleEvent(Event ev) {
String domEventType = ev.getType();
if (domEventType.equals("click")) {
myEngine.setJavaScriptEnabled(true);
myEngine.getLoadWorker().cancel();
ev.preventDefault();
UIUtil.invokeLaterIfNeeded(() -> {
final String href = ((Element)ev.getTarget()).getAttribute("href");
if (href == null) return;
final URI address;
try {
address = new URI(href);
BrowserUtil.browse(address);
}
catch (URISyntaxException e) {
LOG.warn(e.getMessage());
}
});
}
}
}
private static void adjustHeight(final WebView webView, final JFXPanel javafxPanel, String source) {
try {
session.parseInput(input);
XMLStringOutputOptions options = new XMLStringOutputOptions();
options.setIndenting(true);
options.setAddingMathSourceAnnotations(false);
final String xmlString = session.buildXMLString(options);
if (xmlString == null) return;
final LayoutContextImpl context = (LayoutContextImpl)LayoutContextImpl.getDefaultLayoutContext();
context.setParameter(Parameter.MATHCOLOR, UIUtil.getTextAreaForeground());
context.setParameter(Parameter.MATHSIZE, 18);
Object result = webView.getEngine().executeScript("document.getElementById(\"mydiv\").offsetHeight");
if (result instanceof Integer) {
final int fontSize = EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize();
double x = (double)source.length() * 8 / (int)result;
final double height = (source.length() * fontSize) / x + 20;
final int width = (int)(webView.getWidth() == 0 ? 1500 : webView.getWidth());
final Dimension size = new Dimension(width, (int)height);
final Document document = MathMLParserSupport.parseString(xmlString);
final BufferedImage image = Converter.getInstance().render(document, context);
try {
@SuppressWarnings("unchecked")
Dictionary<URL, BufferedImage> cache = (Dictionary<URL, BufferedImage>)editorDocument.getProperty("imageCache");
if (cache == null) {
//noinspection UseOfObsoleteCollectionType
cache = new Hashtable<URL, BufferedImage>();
editorDocument.putProperty("imageCache", cache);
}
final URL u = new URL(ourImagePrefix + imageIndex + ".jpg");
cache.put(u, image);
}
catch (MalformedURLException e) {
LOG.error(e);
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
javafxPanel.setPreferredSize(size);
javafxPanel.revalidate();
javafxPanel.repaint();
}
});
}
}
catch (IOException e) {
LOG.error(e);
catch (JSException ignore) {
}
catch (SAXException e) {
LOG.error(e);
LOG.info("formula text " + formulaText);
}
private static void updateLaf(boolean isDarcula, BorderPane pane, WebEngine engine, JFXPanel jfxPanel) {
if (isDarcula) {
updateLafDarcula(pane, engine, jfxPanel);
}
catch (ParserConfigurationException e) {
LOG.error(e);
}
if (formulaText.startsWith("$$") || formulaText.startsWith("\\begin")) {
result.append("<p style = \"text-align:center;\"><img src=\"").append(ourImagePrefix).append(imageIndex).append(".jpg\"/></p>");
}
else
result.append("<img src=\"").append(ourImagePrefix).append(imageIndex).append(".jpg\"/>");
}
private static void updateLafDarcula(BorderPane pane, WebEngine engine, JFXPanel jfxPanel) {
Platform.runLater(() -> {
ourStyleUrl = IpnbFileType.class.getResource("/style/javaFXBrowserDarcula.css");
engine.setUserStyleSheetLocation(ourStyleUrl.toExternalForm());
pane.setStyle("-fx-background-color: #313335");
jfxPanel.getScene().getStylesheets().add(ourStyleUrl.toExternalForm());
engine.reload();
});
}
}
@@ -183,7 +183,7 @@ public class IpnbFileEditor extends UserDataHolderBase implements FileEditor {
public void actionPerformed(ActionEvent e) {
IpnbReloadKernelAction.reloadKernel(IpnbFileEditor.this);
}
}, AllIcons.Actions.Refresh, "Restart kernel");
}, AllIcons.Actions.Refresh, "Restart Kernel");
}
private void addSaveButton(@NotNull final JPanel controlPanel) {
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.ipnb.editor.actions;
import com.intellij.ide.actions.CreateFileFromTemplateAction;
import com.intellij.ide.actions.CreateFileFromTemplateDialog;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.plugins.ipnb.IpnbFileType;
public class IpnbCreateFileAction extends CreateFileFromTemplateAction implements DumbAware {
public IpnbCreateFileAction() {
super("IPython Notebook", "Creates an IPython Notebook file from the specified template", IpnbFileType.INSTANCE.getIcon());
}
@Override
protected void buildDialog(Project project, PsiDirectory directory, CreateFileFromTemplateDialog.Builder builder) {
builder
.setTitle("New IPython Notebook")
.addKind("IPython Notebook", IpnbFileType.INSTANCE.getIcon(), "IPython Notebook");
}
@Override
protected String getActionName(PsiDirectory directory, String newName, String templateName) {
return "Create IPython Notebook " + newName;
}
}
@@ -162,7 +162,7 @@ public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, D
myIpnbPanels.add(panel);
}
else if (cell instanceof IpnbMarkdownCell) {
panel = new IpnbMarkdownPanel((IpnbMarkdownCell)cell);
panel = new IpnbMarkdownPanel((IpnbMarkdownCell)cell, this);
addComponent(panel);
}
else if (cell instanceof IpnbHeadingCell) {
@@ -369,7 +369,7 @@ public class IpnbFilePanel extends JPanel implements Scrollable, DataProvider, D
panel = new IpnbCodePanel(myProject, myParent, (IpnbCodeCell)cell);
}
else if (cell instanceof IpnbMarkdownCell) {
panel = new IpnbMarkdownPanel((IpnbMarkdownCell)cell);
panel = new IpnbMarkdownPanel((IpnbMarkdownCell)cell, myParent.getIpnbFilePanel());
}
else if (cell instanceof IpnbHeadingCell) {
panel = new IpnbHeadingPanel((IpnbHeadingCell)cell);
@@ -1,5 +1,6 @@
package org.jetbrains.plugins.ipnb.editor.panels;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.ui.components.JBLabel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
@@ -18,7 +19,8 @@ public class IpnbHeadingPanel extends IpnbEditablePanel<JBLabel, IpnbHeadingCell
}
private String renderCellText() {
return "<html><body><h" + myCell.getLevel() + ">" + myCell.getSourceAsString() + "</h" + myCell.getLevel() +
return "<html><body><h" + myCell.getLevel() + " style=\"font-size: " + EditorColorsManager
.getInstance().getGlobalScheme().getEditorFontSize() + ";\">" + myCell.getSourceAsString() + "</h" + myCell.getLevel() +
"></body></html>";
}
@@ -6,10 +6,13 @@ import org.jetbrains.plugins.ipnb.format.cells.IpnbMarkdownCell;
import javax.swing.*;
public class IpnbMarkdownPanel extends IpnbEditablePanel<JEditorPane, IpnbMarkdownCell> {
public class IpnbMarkdownPanel extends IpnbEditablePanel<JComponent, IpnbMarkdownCell> {
public IpnbMarkdownPanel(@NotNull final IpnbMarkdownCell cell) {
private final IpnbFilePanel myParent;
public IpnbMarkdownPanel(@NotNull final IpnbMarkdownCell cell, @NotNull final IpnbFilePanel parent) {
super(cell);
myParent = parent;
initPanel();
}
@@ -19,8 +22,9 @@ public class IpnbMarkdownPanel extends IpnbEditablePanel<JEditorPane, IpnbMarkdo
}
@Override
protected JEditorPane createViewPanel() {
return IpnbUtils.createLatexPane(myCell.getSourceAsString());
protected JComponent createViewPanel() {
int width = myParent.getWidth();
return IpnbUtils.createLatexPane(myCell.getSourceAsString(), width);
}
@Override
@@ -32,6 +36,6 @@ public class IpnbMarkdownPanel extends IpnbEditablePanel<JEditorPane, IpnbMarkdo
@SuppressWarnings("CloneDoesntCallSuperClone")
@Override
protected Object clone() {
return new IpnbMarkdownPanel((IpnbMarkdownCell)myCell.clone());
return new IpnbMarkdownPanel((IpnbMarkdownCell)myCell.clone(), myParent);
}
}
@@ -1,55 +0,0 @@
package org.jetbrains.plugins.ipnb.editor.panels;
import org.w3c.dom.Element;
import uk.ac.ed.ph.snuggletex.SnugglePackage;
import uk.ac.ed.ph.snuggletex.dombuilding.CommandHandler;
import uk.ac.ed.ph.snuggletex.dombuilding.EqnArrayHandler;
import uk.ac.ed.ph.snuggletex.internal.DOMBuilder;
import uk.ac.ed.ph.snuggletex.internal.SnuggleParseException;
import uk.ac.ed.ph.snuggletex.semantics.Interpretation;
import uk.ac.ed.ph.snuggletex.semantics.MathOperatorInterpretation;
import uk.ac.ed.ph.snuggletex.tokens.CommandToken;
import uk.ac.ed.ph.snuggletex.tokens.FlowToken;
import java.util.List;
import static uk.ac.ed.ph.snuggletex.definitions.Globals.ALL_MODES;
import static uk.ac.ed.ph.snuggletex.definitions.Globals.MATH_MODE_ONLY;
import static uk.ac.ed.ph.snuggletex.definitions.LaTeXMode.MATH;
import static uk.ac.ed.ph.snuggletex.definitions.TextFlowContext.START_NEW_XHTML_BLOCK;
public final class IpnbTexPackageDefinitions {
private static final SnugglePackage ourPackage;
public static SnugglePackage getPackage() {
return ourPackage;
}
private static String ourMathCharacters = "org/jetbrains/plugins/ipnb/math-characters.txt";
static {
ourPackage = new SnugglePackage("Ipnb");
ourPackage.addComplexCommandSameArgMode("dot", false, 1, MATH_MODE_ONLY, new CommandHandler() {
@Override
public void handleCommand(DOMBuilder builder, Element parentElement, CommandToken token) throws SnuggleParseException {
List<FlowToken> content = token.getArguments()[0].getContents();
Element result = builder.appendMathMLElement(parentElement, "mover");
builder.handleMathTokensAsSingleElement(result, content);
builder.appendMathMLOperatorElement(result, "\u02D9");
}
}, null);
ourPackage.addComplexCommandSameArgMode("pi", false, 0, MATH_MODE_ONLY, new CommandHandler() {
@Override
public void handleCommand(DOMBuilder builder, Element parentElement, CommandToken token) throws SnuggleParseException {
builder.appendMathMLOperatorElement(parentElement, "\u03c0");
}
}, null);
ourPackage.addEnvironment("eqnarray", ALL_MODES, MATH, Interpretation.TABULAR, new EqnArrayHandler(), START_NEW_XHTML_BLOCK);
ourPackage.addSimpleMathCommand("lt", new MathOperatorInterpretation("<"));
ourPackage.addSimpleMathCommand("gt", new MathOperatorInterpretation(">"));
ourPackage.loadMathCharacterDefinitions(ourMathCharacters);
}
}
@@ -1,7 +1,10 @@
package org.jetbrains.plugins.ipnb.editor.panels.code;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
import org.jetbrains.plugins.ipnb.editor.panels.IpnbFilePanel;
import org.jetbrains.plugins.ipnb.editor.panels.IpnbPanel;
import org.jetbrains.plugins.ipnb.format.cells.output.IpnbOutputCell;
@@ -9,9 +12,11 @@ import javax.swing.*;
import java.awt.*;
public class IpnbCodeOutputPanel<K extends IpnbOutputCell> extends IpnbPanel<JComponent, K> {
protected final IpnbFilePanel myParent;
public IpnbCodeOutputPanel(@NotNull final K cell) {
public IpnbCodeOutputPanel(@NotNull final K cell, @Nullable final IpnbFilePanel parent) {
super(cell, new BorderLayout());
myParent = parent;
myViewPanel = createViewPanel();
add(myViewPanel);
}
@@ -20,6 +25,9 @@ public class IpnbCodeOutputPanel<K extends IpnbOutputCell> extends IpnbPanel<JCo
JTextArea textArea = new JTextArea(myCell.getSourceAsString());
textArea.setLineWrap(true);
textArea.setEditable(false);
final Font font = textArea.getFont();
final Font newFont = new Font(font.getName(), font.getStyle(), EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize());
textArea.setFont(newFont);
textArea.setBackground(IpnbEditorUtil.getBackground());
return textArea;
}
@@ -85,11 +85,11 @@ public class IpnbCodePanel extends IpnbEditablePanel<JComponent, IpnbCodeCell> {
}
else if (outputCell instanceof IpnbHtmlOutputCell) {
addPromptPanel(panel, myCell.getPromptNumber(), promptType,
new IpnbHtmlPanel((IpnbHtmlOutputCell)outputCell));
new IpnbHtmlPanel((IpnbHtmlOutputCell)outputCell, myParent.getIpnbFilePanel()));
}
else if (outputCell instanceof IpnbLatexOutputCell) {
addPromptPanel(panel, myCell.getPromptNumber(), promptType,
new IpnbLatexPanel((IpnbLatexOutputCell)outputCell));
new IpnbLatexPanel((IpnbLatexOutputCell)outputCell, myParent.getIpnbFilePanel()));
}
else if (outputCell instanceof IpnbErrorOutputCell) {
addPromptPanel(panel, myCell.getPromptNumber(), promptType,
@@ -101,7 +101,7 @@ public class IpnbCodePanel extends IpnbEditablePanel<JComponent, IpnbCodeCell> {
}
else if (outputCell.getSourceAsString() != null) {
addPromptPanel(panel, myCell.getPromptNumber(), promptType,
new IpnbCodeOutputPanel<IpnbOutputCell>(outputCell));
new IpnbCodeOutputPanel<IpnbOutputCell>(outputCell, myParent.getIpnbFilePanel()));
}
mainPanel.add(panel);
}
@@ -1,5 +1,6 @@
package org.jetbrains.plugins.ipnb.editor.panels.code;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.JBColor;
import org.jetbrains.annotations.NotNull;
@@ -16,7 +17,7 @@ import java.util.List;
public class IpnbErrorPanel extends IpnbCodeOutputPanel<IpnbErrorOutputCell> {
public IpnbErrorPanel(@NotNull final IpnbErrorOutputCell cell) {
super(cell);
super(cell, null);
}
@Override
@@ -24,6 +25,9 @@ public class IpnbErrorPanel extends IpnbCodeOutputPanel<IpnbErrorOutputCell> {
final List<String> text = myCell.getText();
if (text == null) return new JLabel();
ColorPane ansiColoredPane = new ColorPane();
final Font font = ansiColoredPane.getFont();
final Font newFont = new Font(font.getName(), font.getStyle(), EditorColorsManager.getInstance().getGlobalScheme().getEditorFontSize());
ansiColoredPane.setFont(newFont);
ansiColoredPane.appendANSI(StringUtil.join(text, ""));
ansiColoredPane.setBackground(IpnbEditorUtil.getBackground());
ansiColoredPane.setEditable(false);
@@ -1,29 +1,22 @@
package org.jetbrains.plugins.ipnb.editor.panels.code;
import com.intellij.ui.components.JBLabel;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
import org.jetbrains.plugins.ipnb.IpnbUtils;
import org.jetbrains.plugins.ipnb.editor.panels.IpnbFilePanel;
import org.jetbrains.plugins.ipnb.format.cells.output.IpnbHtmlOutputCell;
import javax.swing.*;
public class IpnbHtmlPanel extends IpnbCodeOutputPanel<IpnbHtmlOutputCell> {
public IpnbHtmlPanel(@NotNull final IpnbHtmlOutputCell cell) {
super(cell);
public IpnbHtmlPanel(@NotNull final IpnbHtmlOutputCell cell, @NotNull final IpnbFilePanel parent) {
super(cell, parent);
}
@Override
protected JComponent createViewPanel() {
final StringBuilder text = new StringBuilder("<html>");
for (String html : myCell.getHtmls()) {
html = html.replace("\"", "'");
text.append(html);
}
text.append("</html>");
final JBLabel label = new JBLabel(text.toString());
label.setBackground(IpnbEditorUtil.getBackground());
label.setOpaque(true);
return label;
final int width = myParent.getWidth();
return IpnbUtils.createLatexPane(StringUtil.join(myCell.getHtmls(), ""), width);
}
}
@@ -3,10 +3,10 @@ package org.jetbrains.plugins.ipnb.editor.panels.code;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Base64;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
import org.jetbrains.plugins.ipnb.format.cells.output.IpnbImageOutputCell;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import javax.swing.*;
@@ -17,7 +17,7 @@ public class IpnbImagePanel extends IpnbCodeOutputPanel<IpnbImageOutputCell> {
private static final Logger LOG = Logger.getInstance(IpnbImagePanel.class);
public IpnbImagePanel(@NotNull final IpnbImageOutputCell cell) {
super(cell);
super(cell, null);
}
@Override
@@ -27,7 +27,7 @@ public class IpnbImagePanel extends IpnbCodeOutputPanel<IpnbImageOutputCell> {
final JBLabel label = new JBLabel();
if (!StringUtil.isEmptyOrSpaces(png)) {
try {
byte[] btDataFile = Base64.decode(png);
byte[] btDataFile = new BASE64Decoder().decodeBuffer(png);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(btDataFile));
label.setIcon(new ImageIcon(image));
}
@@ -41,4 +41,4 @@ public class IpnbImagePanel extends IpnbCodeOutputPanel<IpnbImageOutputCell> {
return label;
}
}
}
@@ -5,19 +5,22 @@ import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.ipnb.IpnbUtils;
import org.jetbrains.plugins.ipnb.editor.IpnbEditorUtil;
import org.jetbrains.plugins.ipnb.editor.panels.IpnbFilePanel;
import org.jetbrains.plugins.ipnb.format.cells.output.IpnbLatexOutputCell;
import javax.swing.*;
public class IpnbLatexPanel extends IpnbCodeOutputPanel<IpnbLatexOutputCell> {
public IpnbLatexPanel(@NotNull final IpnbLatexOutputCell cell) {
super(cell);
public IpnbLatexPanel(@NotNull final IpnbLatexOutputCell cell, @NotNull final IpnbFilePanel parent) {
super(cell, parent);
setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
setBackground(IpnbEditorUtil.getBackground());
}
@Override
protected JComponent createViewPanel() {
return IpnbUtils.createLatexPane(StringUtil.join(myCell.getLatex(), ""));
final int width = myParent.getWidth();
return IpnbUtils.createLatexPane(StringUtil.join(myCell.getLatex(), ""), width);
}
}
@@ -8,7 +8,7 @@ import javax.swing.*;
public class IpnbStreamPanel extends IpnbCodeOutputPanel<IpnbStreamOutputCell> {
public IpnbStreamPanel(@NotNull final IpnbStreamOutputCell cell) {
super(cell);
super(cell, null);
}
@Override
@@ -93,7 +93,7 @@ public class PyProtectedMemberInspection extends PyInspection {
private boolean isImportFromTheSamePackage(PyReferenceExpression importSource) {
PsiDirectory directory = importSource.getContainingFile().getContainingDirectory();
if (PyUtil.isPackage(directory, true, importSource.getContainingFile()) &&
if (directory != null && PyUtil.isPackage(directory, true, importSource.getContainingFile()) &&
directory.getName().equals(importSource.getName())) {
return true;
}