Skip to content

Commit

Permalink
default file encoding UTF-8 if specified encoding is not supported by…
Browse files Browse the repository at this point in the history
… JRuby #258
  • Loading branch information
ahus1 committed May 24, 2019
1 parent 7820367 commit 6e14274
Showing 1 changed file with 70 additions and 29 deletions.
99 changes: 70 additions & 29 deletions src/main/java/org/asciidoc/intellij/AsciiDoc.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ServiceConfigurationError;
import java.util.function.IntConsumer;
import java.util.logging.Logger;

Expand All @@ -51,12 +52,16 @@
import org.asciidoctor.AttributesBuilder;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.asciidoctor.jruby.internal.AsciidoctorCoreException;
import org.asciidoctor.log.LogHandler;
import org.asciidoctor.log.LogRecord;
import org.asciidoctor.log.Severity;
import org.jcodings.EncodingDB;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jruby.exceptions.MainExitException;
import org.jruby.platform.Platform;
import org.jruby.util.ByteList;
import org.jruby.util.SafePropertyAccessor;

/**
* @author Julien Viet
Expand Down Expand Up @@ -97,7 +102,7 @@ private void initWithExtensions(List<String> extensions) {
synchronized (AsciiDoc.class) {
boolean extensionsEnabled;
AsciiDocApplicationSettings asciiDocApplicationSettings = AsciiDocApplicationSettings.getInstance();
if(extensions.size() > 0) {
if (extensions.size() > 0) {
asciiDocApplicationSettings.setExtensionsPresent(projectBasePath, true);
}
String md;
Expand All @@ -118,6 +123,24 @@ private void initWithExtensions(List<String> extensions) {
ByteArrayOutputStream boasErr = new ByteArrayOutputStream();
SystemOutputHijacker.register(new PrintStream(boasOut), new PrintStream(boasErr));
LogHandler logHandler = new IntellijLogHandler("initialize");
String oldEncoding = null;
if (Platform.IS_WINDOWS) {
/* There is an initialization procedure in Ruby.java that will abort
when the encoding in file.encoding is not known to JRuby. Therefore default to UTF-8 in this case
as a most sensible default. */
String encoding = System.getProperty("file.encoding", "UTF-8");
ByteList bytes = ByteList.create(encoding);
EncodingDB.Entry entry = EncodingDB.getEncodings().get(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
if(entry == null) {
entry = EncodingDB.getAliases().get(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
}
if(entry == null) {
// this happes for example with -Dfile.encoding=MS949 (Korean?)
oldEncoding = encoding;
log.warn("unsupported encoding " + encoding + " in JRuby, defaulting to UTF-8");
System.setProperty("file.encoding", "UTF-8");
}
}
try {
Thread.currentThread().setContextClassLoader(AsciiDocAction.class.getClassLoader());
asciidoctor = Asciidoctor.Factory.create();
Expand All @@ -135,15 +158,17 @@ private void initWithExtensions(List<String> extensions) {
if (is == null) {
throw new RuntimeException("unable to load script plantuml-png-patch.rb");
}
if(extensionsEnabled) {
if (extensionsEnabled) {
for (String extension : extensions) {
asciidoctor.rubyExtensionRegistry().requireLibrary(extension);
}
}
asciidoctor.rubyExtensionRegistry().loadClass(is);
hash = md;
}
finally {
} finally {
if (oldEncoding != null) {
System.setProperty("file.encoding", oldEncoding);
}
if (asciidoctor != null) {
asciidoctor.unregisterLogHandler(logHandler);
}
Expand All @@ -155,7 +180,8 @@ private void initWithExtensions(List<String> extensions) {
}
}

/** Calculate a hash for the extensions.
/**
* Calculate a hash for the extensions.
* Hash will change if the project has been changed, of the contents of files have changed.
* TODO: hash will not change if files referenced in extensions changed.
*/
Expand All @@ -171,8 +197,7 @@ private String calcMd(String projectBasePath, List<String> extensions) {
} finally {
IOUtils.closeQuietly(is);
}
}
catch (IOException e) {
} catch (IOException e) {
throw new RuntimeException("unable to read file", e);
}
}
Expand All @@ -182,8 +207,7 @@ private String calcMd(String projectBasePath, List<String> extensions) {
sb.append(Integer.toString((mdbyte & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
catch (NoSuchAlgorithmException e) {
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("unknown hash", e);
}
}
Expand Down Expand Up @@ -227,13 +251,13 @@ public static String prependConfig(Document document, Project project, IntConsum
VirtualFile currentFile = FileDocumentManager.getInstance().getFile(document);
StringBuilder tempContent = new StringBuilder();
VirtualFile folder = currentFile.getParent();
if(folder != null) {
if (folder != null) {
while (true) {
VirtualFile configFile = folder.findChild(".asciidoctorconfig");
if (configFile != null &&
!currentFile.equals(configFile)) {
Document config = FileDocumentManager.getInstance().getDocument(configFile);
if(config != null) {
if (config != null) {
// prepend the new config, followed by two newlines to avoid sticking-together content
tempContent.insert(0, "\n\n");
tempContent.insert(0, config.getText());
Expand Down Expand Up @@ -286,25 +310,42 @@ public String render(String text, List<String> extensions) {

public String render(String text, List<String> extensions, Notifier notifier) {
synchronized (AsciiDoc.class) {
initWithExtensions(extensions);
ClassLoader old = Thread.currentThread().getContextClassLoader();
ByteArrayOutputStream boasOut = new ByteArrayOutputStream();
ByteArrayOutputStream boasErr = new ByteArrayOutputStream();
SystemOutputHijacker.register(new PrintStream(boasOut), new PrintStream(boasErr));
CollectingLogHandler logHandler = new CollectingLogHandler();
asciidoctor.registerLogHandler(logHandler);
try {
Thread.currentThread().setContextClassLoader(AsciiDocAction.class.getClassLoader());
return "<div id=\"content\">\n" + asciidoctor.convert(text, getDefaultOptions()) + "\n</div>";
} catch (AsciidoctorCoreException ace) {
log.warn("unable to render AsciidDoc document", ace);
logHandler.log(new LogRecord(Severity.FATAL, ace.getMessage()));
return "unable to render AsciidDoc document: " + ace.getMessage() + "<p>(the full exception stack trace is available in the IDE's log file)";
} finally {
asciidoctor.unregisterLogHandler(logHandler);
SystemOutputHijacker.deregister();
notifier.notify(boasOut, boasErr, logHandler.getLogRecords());
Thread.currentThread().setContextClassLoader(old);
initWithExtensions(extensions);
ClassLoader old = Thread.currentThread().getContextClassLoader();
ByteArrayOutputStream boasOut = new ByteArrayOutputStream();
ByteArrayOutputStream boasErr = new ByteArrayOutputStream();
SystemOutputHijacker.register(new PrintStream(boasOut), new PrintStream(boasErr));
asciidoctor.registerLogHandler(logHandler);
try {
Thread.currentThread().setContextClassLoader(AsciiDocAction.class.getClassLoader());
return "<div id=\"content\">\n" + asciidoctor.convert(text, getDefaultOptions()) + "\n</div>";
} finally {
asciidoctor.unregisterLogHandler(logHandler);
SystemOutputHijacker.deregister();
notifier.notify(boasOut, boasErr, logHandler.getLogRecords());
Thread.currentThread().setContextClassLoader(old);
}
} catch (Exception | ServiceConfigurationError ex) {
log.warn("unable to render AsciiDoc document", ex);
logHandler.log(new LogRecord(Severity.FATAL, ex.getMessage()));
StringBuilder response = new StringBuilder();
response.append("unable to render AsciiDoc document");
Throwable t = ex;
do {
response.append("<p>").append(t.getClass().getCanonicalName()).append(": ").append(t.getMessage());
if (t instanceof MainExitException && t.getMessage().startsWith("unknown encoding name")) {
response.append("<p>Either your local encoding is not supported by JRuby, or you passed an unrecognized value to the Java property 'file.encoding' either in the IntelliJ options file or via the JAVA_TOOL_OPTION environment variable.");
String property = SafePropertyAccessor.getProperty("file.encoding", null);
response.append("<p>encoding passed by system property 'file.encoding': ").append(property);
response.append("<p>available encodings (excuding aliases): ");
EncodingDB.getEncodings().forEach(entry -> response.append(entry.getEncoding().getCharsetName()).append(" "));
}
t = t.getCause();
} while (t != null);
response.append("<p>(the full exception stack trace is available in the IDE's log file. Visit menu item 'Help | Show Log in Explorer' to see the log)");
return response.toString();
}
}
}
Expand Down

0 comments on commit 6e14274

Please sign in to comment.