intellij scala built-in formatter messing up partial functions - scala

i'm trying to convince the built-in intellij scala formatter to format a partial function as a parameter like this:
PersistenceQuery(context.system)
.readJournalFor[ScalaDslMongoReadJournal](MongoReadJournal.Identifier)
.eventsByPersistenceId(persistenceId, 0, Long.MaxValue)
.map(_.event)
.collect[Thing]({
case e:Foo => e // note the indentation
}) // aligned with the .
.runWith(Sink.asPublisher(fanout = false))
but, the best i can get is:
PersistenceQuery(context.system)
.readJournalFor[ScalaDslMongoReadJournal](MongoReadJournal.Identifier)
.eventsByPersistenceId(persistenceId, 0, Long.MaxValue)
.map(_.event)
.collect[Thing]({
case e:Foo => e // unindented
}) // *under* indented!
.runWith(Sink.asPublisher(fanout = false))
i'd prefer to use the built-in formatter over an external one.
anybody know what the right configuration incantation looks like?
intellij 2017.2.1
scala plugin 2017.2.13

Related

Scalafmt force curly braces style over indentation

I am trying to force curly braces style for my scala project. I have written below config for scalafmt:
version = "3.7.1"
runner.dialect = scala3
maxColumn = 80
rewrite.rules = [Imports]
rewrite.insertBraces.ifElseExpressions = true
But when I apply this config for file with below lines of code, I don't see any change performed by scalafmt. How I can fix this? and Is there any better way to force curly braces style for everything i.e. function definitions, class definition etc.
if (sortedList.isEmpty) new Cons(x, empty)
else if (compare(x, sortedList.head) <= 0) new Cons(x, sortedList)
else new Cons(sortedList.head, insert(x, sortedList.tail))
SBT version: 1.6.2

I am getting an Invalid syntax while applying filter to my Spark Context (sc)

I am getting an invalid syntax error when running code in pyspark Python 3 notebook, looks like the original code I am studying and practising with is in scala and syntax is slightly different ...
the issue appears to be related to the '=>' operator but cant seem to figure out the correct one to use as I am still new to this language
for i in range(1980, 2016):
print(i)
yearStats = sc.textFile("./BasketballStats-master.zip\BasketballStats-master\data\leagues_NBA_$i*")
yearStats.filter(x => x.contains(",")).map(x => (i,x)).saveAsTextFile("./BasketballStats\$i")
you are mixing the syntax of Scala and Python. You have written For Loop in Python and rest of code in Scala.
Python Code
for i in range(1980, 2016):
print(i)
yearStats = sc.textFile("./BasketballStats-master.zip\BasketballStats-master\data\leagues_NBA_$i*")
yearStats.filter(lambda x : x.contains(",")).map( lambda x: (i,x)).saveAsTextFile("./BasketballStats")
Scala Code
for (i <- 1980 to 2016){
prinln(i)
yearStats = sc.textFile("./BasketballStats-master.zip\BasketballStats-master\data\leagues_NBA_$i*")
yearStats.filter(x => x.contains(",")).map(x => (i,x)).saveAsTextFile("./BasketballStats")
}

How do I set the console cursor position in scala?

I'm trying to put a simple console spinner into my scala application, but I'm not sure how to set the cursor position?
If it's not possible, is there another way of achieving this?
val chars = List("/", "-", "\\", "|")
(0 to 30).foreach { _ => chars.foreach { cc =>
print(s"\u0008$cc")
Thread.sleep(150)
}
}
Idea taken from that answer:
Write to same location in a console window with java

ScalaJS to emit EmberJS code?

I want to write Scala code that can be then translated to EmberJS code.
Can it be done? If not out of the box any suggestion as to how that can be achieved by hacking ScalaJS?
Regards.
Scala.js can emit any kind of JavaScript code, so technically the answer is yes. However, since Ember requires you to define "components" using classes of sorts of its own design, it can be a bit ugly to write in Scala.js. For example, this example taken from the front page:
App.GravatarImageComponent = Ember.Component.extend({
size: 200,
email: '',
gravatarUrl: function() {
var email = this.get('email'),
size = this.get('size');
return 'http://www.gravatar.com/avatar/' + hex_md5(email) + '?s=' + size;
}.property('email', 'size')
});
would have to be written in Scala.js as:
import scala.scalajs.js
import js.Dynamic.{global => g, literal => lit}
g.App.GravatarImageComponent = g.Ember.Component.extend(lit(
size = 200,
email = "",
gravatarUrl = ({ (ths: js.Dynamic) =>
val email = ths.get("email")
val size = ths.get("size")
s"http://www.gravatar.com/avatar/${g.hex_md5(email)}?s=$size"
}: js.ThisFunction).asInstanceOf[js.Dynamic].property("email", "size")
))
which is, well ... JavaScript-ish.
Powerful UI libraries for JavaScript kind of rely so much on the dynamic and weird aspects of JavaScript that they don't fit super well in Scala.js. I am planning to write a React.js-like UI library specifically designed for Scala.js this semester to address this issue.

Is there a way to include math formulae in Scaladoc?

I would like to enter math formulae in Scaladoc documentation of mathematical Scala code. In Java, I found a library called LatexTaglet that can do exactly this for Javadoc, by writing formulae in Latex:
http://latextaglet.sourceforge.net/
And it seems to integrate well with Maven (reporting/plugins section of a POM). Is there an equivalent library for Scaladoc? If not, how could I integrate this library with SBT?
I also considered using MathML (http://www.w3.org/Math/), but looks too verbose. Is there an editor you would recommend? Does MathML integrate well with Scaladoc?
Thank you for your help!
To follow on #mergeconflict answer, here is how I did it
As there is no proper solution, what I did is to implement a crawler that parse all generated html files, and replace any found "import tag" (see code below), by the import of the MathJax script:
lazy val mathFormulaInDoc = taskKey[Unit]("add MathJax script import in doc html to display nice latex formula")
mathFormulaInDoc := {
val apiDir = (doc in Compile).value
val docDir = apiDir // /"some"/"subfolder" // in my case, only api/some/solder is parsed
// will replace this "importTag" by "scriptLine
val importTag = "##import MathJax"
val scriptLine = "<script type=\"text/javascript\" src=\"https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\"> </script>"
// find all html file and apply patch
if(docDir.isDirectory)
listHtmlFile(docDir).foreach { f =>
val content = Source.fromFile(f).getLines().mkString("\n")
if(content.contains(importTag)) {
val writer = new PrintWriter(f)
writer.write(content.replace(importTag, scriptLine))
writer.close()
}
}
}
// attach this task to doc task
mathFormulaInDoc <<= mathFormulaInDoc triggeredBy (doc in Compile)
// function that find html files recursively
def listHtmlFile(dir: java.io.File): List[java.io.File] = {
dir.listFiles.toList.flatMap { f =>
if(f.getName.endsWith(".html")) List(f)
else if(f.isDirectory) listHtmlFile(f)
else List[File]()
}
}
As you could see, this crawler task is attached to the doc task, to it is done automatically by sbt doc.
Here is an example of doc that will be rendered with formula
/**
* Compute the energy using formula:
*
* ##import MathJax
*
* $$e = m\times c^2$$
*/
def energy(m: Double, c: Double) = m*c*c
Now, it would be possible to improve this code. For example:
add the script import in the html head section
avoid reading the whole files (maybe add a rule that the import tag should be in the first few lines
add the script to the sbt package, and add it to the target/api folder using some suitable task
The short answer is: no. LaTeXTaglet is made possible by the JavaDoc Taglet API. There is no equivalent in Scaladoc, therefore no clean solution.
However, I can think of a hack that might be easy enough to do:
There's a library called MathJax, which looks for LaTeX-style math formulae in an HTML page and dynamically renders it in place. I've used it before, it's pretty nice; all you have to do is include the script. So you could do two things:
Edit and rebuild the Scaladoc source to include MathJax, or...
Write a little post-processor crawl all of Scaladoc's HTML output after it runs, and inject MathJax into each file.
That way, you could just write LaTeX formulae directly in your Scala comments and they should be rendered in the browser. Of course if you wanted a non-hacky solution, I'd suggest you create a taglet-like API for Scaladoc ;)
The forthcoming scala3 aka Dotty has in-built support for markdown which allows rendering simple math formulas using a subset of Latex.
I solved this by using the same approach as Spark did.
Put this JavaScript in a file somewhere in your project:
// From Spark, licensed APL2
// https://github.com/apache/spark/commit/36827ddafeaa7a683362eb8da31065aaff9676d5
function injectMathJax() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.onload = function(){
MathJax.Hub.Config({
displayAlign: "left",
tex2jax: {
inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ],
displayMath: [ ["$$","$$"], ["\\[", "\\]"] ],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'a']
}
});
};
script.src = ('https:' == document.location.protocol ? 'https://' : 'http://') +
'cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML';
document.getElementsByTagName('head')[0].appendChild(script);
}
document.addEventListener('DOMContentLoaded', injectMathJax)
and this little bit into your build.sbt:
lazy val injectMathJax = taskKey[Unit]("Injects MathJax Javascript into Scaladoc template.js")
injectMathJax := {
val docPath = (Compile / doc).value
val templateJsOutput = docPath / "lib" / "template.js"
streams.value.log.info(s"Adding MathJax initialization to $templateJsOutput")
// change this path, obviously
IO.append(templateJsOutput, IO.readBytes(file("doc/static/js/mathjax_init.js")))
},
injectMathJax := (injectMathJax triggeredBy (Compile / doc)).value
I'll eventually get around to building and publicly releasing a plugin for this, as I'm likely going to be using Scala 2.x for a very long time.
Caveats to this approach:
Formulae must be in $ or $$ in Scaladoc comments.
It's best to further enclose them in the comment with another element. I've been using <blockquote>.
For at least the Scaladoc included with Scala 2.11.x, a formula will only show on class, object, and trait top-level symbols. Something in the toggle to show the full comment breaks when MathJax-inject elements are present. I've not figured it out yet, but if I do, I'll submit a patch to Scaladoc directly.
Example:
/**
* A Mean Absolute Scaled Error implementation
*
* Non-seasonal MASE formula:
* <blockquote>
* $$
* \mathrm{MASE} = \mathrm{mean}\left( \frac{\left| e_j \right|}{\frac{1}{T-1}\sum_{t=2}^T \left| Y_t-Y_{t-1}\right|} \right) = \frac{\frac{1}{J}\sum_{j}\left| e_j \right|}{\frac{1}{T-1}\sum_{t=2}^T \left| Y_t-Y_{t-1}\right|}
* $$
* </blockquote>
**/
object MeanAbsoluteScaledError {