I'm writing a JavaScript library which outputs SVG diagrams. To calculate layout of these diagrams the library requires font metrics to make diagram shapes fit text in them.
I want this library to be usable in both web pages and command line for batch rendering.
In the browser, fonts are available and I can get text metrics via Canvas API. It works fine.
In the command line, there are system fonts and stuff like QFontMetric. I can use Qt Script to run the library. It is also quite easy to integrate PDF and PNG exports. But that would mean to write wrapper in Qt.
The question: Does Node.js have a support to access system fonts and get their metric? Or is there a better way to implement such CLI tool based on JS library?
Node.js does not have built-in functionality for this, but there are certainly npm packages out there to get those metrics.
A quick googling brought up a package called fontmetrics, which seems to do exactly what you asked for.
Related
One of the major “selling” points of Kotlin appears to be its ability to compile both to JVM or Android and to JavaScript for the web. To make use of this, it should be possible to have a code base where some files are shared between an Android App and a browser Web App.
However, so far I found little details on how such a thing would be set up, in particularly when working with Android Studio and its underlying Gradle setup, starting from a a run of the Android Studio New Project Wizard. I don't mind if I can only build the Web App on the command line, but I'd like to maintain the Android debugging hookups that Android Studio provides. So far I know very little about Gradle and typical idioms for its use.
I'm sure that I'm not the first person to have this idea, so I'd like to know some best practices on how to set this up. Questions that come to my mind include the following:
Do I mix the kotlin2js and the kotlin-android plugin in a single build file, or do I need to have multiple build files (perhaps I should say “modules” or “projects” except I don't know which)?
If I have multiple build files, should that be two (one Android one Web) or three (one more for shared things)?
If it is two build files, how do I reference the shared sources?
If it is three build files, which plugin(s) do I use for the shared one?
Do I need to split my sources over three different source trees? Are there any conventions how these should be called?
Do I need to split my classes into three groups of packages, or can code for different targets coexist in the same package?
What configuration settings do I need to tweak to make the IDE aware of the layout of my project?
I've read the following relevant documentation, among other:
https://kotlinlang.org/docs/reference/using-gradle.html
https://docs.gradle.org/current/userguide/intro_multi_project_builds.html
https://docs.gradle.org/current/userguide/composite_builds.html
https://kotlinlang.org/docs/tutorials/kotlin-android.html
I would recommend using IDEA wizard to create a simple multiplatfrom project for you (File -> New -> Project -> Kotlin -> Kotlin (Multiplatform - experimental) ). Community edition should suffice.
Answering your questions:
You don't mix plugins. You create a separate module for your common code and use 'kotlin-platform-common' plugin for it.
Three modules, special plugin 'kotlin-platform-common'
Use common sense for source splitting. Put whatever you want/able to reuse in the common code. Put platform-specific code in platform modules.
No package restrictions. You can put everything in the same package if you so desire =)
Pretty sure it should just work. If not, try re-importing.
I'm interested in using Cesium to build a 3D Earth with custom tiles, but as per the "get started" instructions here, it seems as though you have to download a massive 30mb directory and include the whole thing in your project to have it run correctly. Is this true? Can I not just include Cesium.js and get running like that? I don't need 80% of the UI elements they include anyways.
At the end of the "get started" tutorial, they seem to indicate that all you need to get running are these bits:
<script src="Cesium/Cesium.js"></script>
#import url(Cesium/Widgets/widgets.css);
<div id="cesiumContainer"></div>
var viewer = new Cesium.CesiumViewer('cesiumContainer');
But when I set these bits up, I get this error: "define is not defined" and "Cesium is not defined".
What is the lightest possible way to run Cesium?
That tutorial definitely needs an update and I'll make a note to clean it up. (For starters, there's a bug at the bottom of it, because Cesium.CesiumViewer should just be Cesium.Viewer.) That being said, here's the low-down on what's included in the zip and what you'll want/need for actual development.
Apps -> Sample applications.
Source -> AMD modules for module-based development (requirejs, browserify, etc..) also used by the sample applications.
Specs -> Unit tests.
ThirdParty -> Third party libraries required for the above.
Build/Apps -> Built and minified versions of the sampled applications.
Build/Documentation -> The reference documentation.
This leaves two directories, Build/Cesium and Build/CesiumUnminified, which I'll talk about in a minute.
But first, the technically correct answer to your question is to create the lightest possible Cesium-based application, use the AMD modules we provide. This means you only need to include the Source folder at development time, and then your build process will create the minified and concatenated version of your app for deployment. Using modules ensure you only include the Cesium features you are using. This is different than the "traditional" web development practice of including minified versions of all of your code and libraries in the correct order via script tags at the bottom of your page. Modules are gaining momentum on a daily basis and ES6 along with build systems like Babel are slowly taking over the web dev landscape. We use requirejs ourselves, but there are tons of options out there.
An example of an application built this way is the Cesium Viewer example in Build\Apps\CesiumViewer (source is in Apps\CesiumViewer). The entire built app (uncompressed) is 8.77 megs and exposes pretty much every Cesium feature and capability. 3.65 megs of that is the Natural Earth imagery that ships by default and other data files that the app only pulles down on demand if you use a feature that triggers it. The remaining JavaScript is greatly reduced in size by gzipping compression on the server end. To see this for yourself, run the latest Cesium Viewer link and open the network tab in your browser dev tools. The entire app only sucks down 2.2 megs (and that includes the initial imagery being loaded from Bing. The Cesium portion is only about 426kb. It might suck down a few extra kb if you start loading GeoJSON or KML files, but not much.
Since a module based approach requires additional set up and is still not that common in web development overall, we also supply the Build/Cesium and Build/CesiumUnminified folders. These included fully minified and concatenated versions of Cesium that suck all of the modules into a single file. However, you need more than just the Cesium.js file for deployment. Here's a break down of these folders:
Build/Assets -> The default imagery/assets that ship with Cesium (imagery/icons/stars/data for ICRF transformations). This data is pulled down as needed depending on how you configure your Cesium application. It's 3.65 megs, but chanes are your app will only ever touch a few kb of that (depending on the features you use). Rather than try and determine what to deploy to the server, I suggest deploying the entire directory (but as I said, the client may never retrieve most of it).
Build/Workers and Build/ThirdParty -> These contained the concatenated web workers used by Cesium. This includes code used by imagery/terrain, geometry tessellation, and zip file handling. It's pulled down on demand and even if you did something to require all of it, is still under a meg gzipped. These files can't be included in the primary Cesium.js because of the nature of WebWorkers (In our opinion this is a difficiency in the spec).
Build/Widgets -> contains the concatenated CSS, both in inidividual widget form and in a combined widgets.css file. I recommend just including widgets.css and be done with it (4kb gzipped); but if you are really concerned about size you can bring down individual css files. This folder also contains icons used by the various widgets. Once again, they are only retrieved from the server if needed.
As their names suggestions, Both Build/Cesium and Build/CesiumUnminified are pretty much the same thing. The main difference is that Build/Cesium has been minified and is much smaller. It is also faster because it has a lot of debug code removed in order to improve performance. Our official recommendation is to develop against CesiumUnminified and deploy using Cesium. This will make it easier to develop because you'll get better error handling and callstacks if there are problems in your code.
An example of an application built this way is the Hello World application link. There's actually not much size difference from the built Cesium Viewer app I linked above, but that's because they are essentially the same application built two different ways.
So this answer ended up being a lot longer than I wanted it to be, but Web Development is varied and Cesium tries to do its best to support all of its different approaches. Cesium itself is also incredibly ambitious so we've had to overcome a lot of hurdles that other projects never encounter. Is there room for improvement, absolutely, but we go out of our way to ensure that Cesium is as light as it can be while delivering the features that it has. I think in a 2.0 version we will probably take this even further and try and make things more modular.
I hope that answers your questions and concerns.
i'm making a research for the topic of getting a mp3 file rendered as waveform. i've already found some php libraries. now i'm looking for a similar solution in nodejs.
my results so far are:
https://github.com/afreiday/php-waveform-svg
http://www.schillmania.com/projects/soundmanager2/ (maybe loading this in nodejs to try rendering the wave file in svg-format... not quiet sure)
have you guys experience with nodejs-libraries to create waveforms in svg format?
Not a directly nodejs-related solution.
We use a Linux commandline tool Sonic Annotator to extract waveform (peaks) and detect beat in audio files. Its a host that can run VAMP plugins that are quite good at these tasks.
Peaks are extracted as a set of floats from 0 to 1 at equal intervals. SHould be rather simple to build an svg on top of that data (with D3 i.e.).
I'm not used to nodejs, but the docs says it can run external commands.
So we're writing a full-text search framework MongoDb. MongoDB is pretty much javascript-native, so we wrote the javascript library first, and it works.
Now I'm trying to write a python framework for it, which will be partially in python, but partially use those same stored javascript functions - the javascript functions are an intrinsic part of the library. On the other hand, the javascript framework does not depend on python. since they are pretty intertwined it seems like it's worthwhile keeping them in the same repository.
I'm trying to work out a way of structuring the whole project to give the javascript and python frameworks equal status (maybe a ruby driver or whatever in the future?), but still allow the python library to install nicely.
Currently it looks like this: (simplified a little)
javascript/jstest/test1.js
javascript/mongo-fulltext/search.js
javascript/mongo-fulltext/util.js
python/docs/indext.rst
python/tests/search_test.py
python/tests/__init__.py
python/mongofulltextsearch/__init__.py
python/mongofulltextsearch/mongo_search.py
python/mongofulltextsearch/util.py
python/setup.py
I've skipped out a few files for simplicity, but you get the general idea; it' a pretty much standard python project... except that it depends critcally ona whole bunch of javascript which is stored in a sibling directory tree.
What's the preferred setup for dealing with this kind of thing when it comes to setuptools? I can work out how to use package_data etc to install data files that live inside my python project as per the setuptools docs.
The problem is if i want to use setuptools to install stuff, including the javascript files from outside the python code tree, and then also access them in a consistent way when I'm developing the python code and when it is easy_installed to someone's site.
Is that supported behaviour for setuptools? Should i be using paver or distutils2 or Distribute or something? (basic distutils is not an option; the whole reason I'm doing this is to enable requirements tracking) How should i be reading the contents of those files into python scripts?
The short answer is that none of the Python distribution tools is going to do what you want, the exact way you want it. Even if you use distutils' data_files feature, you're still going to have to have your javascript files copied into your Python project directory (i.e., somewhere under the same directory as your setup.py.)
Given that, you might as well just copy the .js files to your package (i.e. alongside mongofulltextsearch/init.py) as part of your build process, and use package_data or include_package_data=True.
(Or alternatively, you could possibly use symlinks, externals, or some such, if your revision control system supports those. I believe that when building source distributions, the Python distribution tools convert symlinks to real files. At least, you could give that a try.)
Given a need to write command line utilities to do common tasks like uploading files to a remote FTP site, downloading data from a remote MySQL database etc.
Is it practical to use JavaScript for this sort of thing? I know there are JavaScript interpreters that can be run from the command line, but are there libraries for things like FTP and database access the way there are for e.g. Java? If so, what's the best place to look for them? (Google searches with JavaScript in the keywords always seem to return many pages of browser specific things.)
And is there a way to package a JavaScript program up as a standalone executable on Windows?
Update: I've decided Python is a better tool for this kind of job, but the answers to the original question are still good ones.
Standalone executable?
By the way you ask the question, I'm not sure if you are aware, but the Windows Script Host - included in Windows - allows you to run .js files from the command-line. Your javascript will not be an executable, it will remain a script, a text file. The script runs within cscript.exe, which is provided by WSH. There's no compilation required. Maybe you knew all that.
I use Javascript this way for various utilities on Windows.
I think your instinct is right on the availability of libraries. You are sort of on your own to find all those things. Although, once you find them, it's not hard to package Javascript libraries as COM components and allow re-use from anywhere. See here for an example of packaging the Google Diff/Patch/Match Javascript library in COM.
Addendum: Once a bit of code is available within COM, it can be consumed by any Javascript running on the machine. Some examples of COM objects available to Javascript scripts running in WSH:
MSXML2.XMLHTTP object - used in AJAX, but can be used for any HTTP communication. There also an object for the XSLT engine so you can do transforms from script.
Excel.Application - allows you to open up Excel spreadsheets and automate them from Javascript.
Communicator.UIAutomation - automate MS Communicator (send IM's via script)
COM objects for Google Earth.
SlowAES - an all-Javascript implementation of AES encryption.
You can use Rhino to compile Javascript into Java byte code, and get access to all Java libraries.
Or you could use JScript.net, and get access to the .net libraries. .net includes a jsc.exe that produces exe-files.
Both of these requires the respective framework to be installed to be able to run.
Node.js is by far the best environment for running non-browser JS. I've used Rhino and SpiderMonkey, and there's a pretty huge difference in everything from the basics like how errors are handled to the size of the community using the tool. Node is pitched for "server-side" JS - building server apps in JS. It's great for this. But it works equally well for building command line tools.
The NPM package manager (bundled with Node) provides a nice global directory for finding and installing packages. It works much better than other language equivalents like PECL / Pear / CPAN / etc. Several high quality tools like JSHint, The Jade templating language, and the CoffeeScript compiler are all already available through NPM/Node:
npm install -g jshint, coffee-script, jade
jshint my_code.js
jade < my.jade > my.html
For args parsing, there are packages like commander.js. I currently use a heavily extended version of Commander in my underscore-cli command-line tool.
For messing with JSON or for doing command-line JS work (similar to "perl -pe"), check out underscore-cli - It's a really powerful tool for processing JSON data, processing underscore templates, and running JS expressions from the command-line. I use it for 1001 different things that would otherwise be really annoying to accomplish.
Rhino is bundled with JDK 1.6, jrunscript.exe in the bin directory will allow you to run any Javascript you want. Since it runs under Java you get access to any Java libraries that you may have.
We use it from the command line extensively. It's very good at that.
One way is to write these utilities as AIR applications - They can be written in JavaScript and need not have a UI. They have access to the command line, and there are existing ActionScript 3 libraries that can handle FTP etc. These ActionScript APIs can be called from JS, in AIR applications. AIR applications also have access to a sqlite database.
jslibs is a good standalone JavaScript runtime that support many 3rd party open source libraries like zlib, SQLite, NSPR, libiconv, libTomCrypt, OpenGL, ...