Developer Zone

Advanced Software Development with MATLAB

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Open and extensible 11

Posted by Arvind Hosagrahara,

MATLAB is an open and extensible platform unique in its ability to dovetail with best-in-class technologies. Open, refers to the fact that much of MATLAB functionality is shipped in MATLAB files whose source can be studied. The community driven contributions on File Exchange has grown over the years to a scale that rivals the code that ships on the DVD. Extensible, refers to MATLAB's ability to integrate with other languages and technology stacks.

MATLAB's extensibility provides access to a wide variety of functionality in C/C++, Java, .NET, Perl, Python, etc. Some 3rd party libraries such as Xerces™ (for processing XML) are baked into the shipping MATLAB product itself.

MATLAB is designed to be extensible, for example, the MEX interface provides access to nearly all of FORTRAN and C/C++ functionality for the expression of numeric algorithms.

Leveraging the extensibility of MATLAB - the Triple-word-score

How does MATLAB's extensibility help you in your day-to-day life?

An immediate problem and answer to this question presented itself in the authoring of content for this very blog. You may have noticed the "published in MATLAB" at the very bottom of this blog post.

Bloggers on this site often use MATLAB for authoring their content and I am no exception. A spellchecker is always helpful when writing. Since I use the MATLAB editor, there is an immediate need to simplify my workflow by providing easy access to spellcheck from the MATLAB environment itself.

A spellchecker could benefit other users so I quickly drew up a list of requirements. A MATLAB spellchecker needed to be:

  • lightweight and free (i.e. be accessible across most versions of MATLAB)
  • cross-platform (i.e. work with our Windows, Mac and Linux releases)
  • multi-lingual (i.e. make no assumptions around use of English as we have over a million users worldwide)
  • customizable (i.e. allow for the modification of word lists)
  • easy-to-build-and-use (i.e. not turn into a huge project in itself)

The first step was to ensure that I was not re-inventing the wheel. A quick File Exchange search and follow-up internet searches turned up nothing.

Not finding what I needed, I decided to build a spellchecker by leveraging existing technology with a little MATLAB effort. I call extending MATLAB functionality a "triple-word-score" since it nets large increments in productivity with minimal effort.

Putting it together by NOT re-inventing the wheel

Given the cross-platform requirement, I quickly eliminated the .NET options and settled for a Java library with a clean API. Jazzy had an aging codebase but a clean API and a full set of language dictionaries which fit my requirements well. It allowed me to put a check against the cross-platform and lightweight and free requirements.

The Jazzy API lends itself to integration through a simple wrapper in Java which allows for a cleaner calling interface. To build our Java class (SpellCheck.java), I fired up a Java IDE and imported the Jazzy libraries from Sourceforge:

/* Package Specification*/
package com.mathworks.spellcheck;

/* Jazzy Imports */
import com.swabunga.spell.engine.SpellDictionary;
import com.swabunga.spell.engine.SpellDictionaryHashMap;
import com.swabunga.spell.event.SpellCheckEvent;
import com.swabunga.spell.event.SpellCheckListener;
import com.swabunga.spell.event.SpellChecker;
import com.swabunga.spell.event.StringWordTokenizer;

/* Java Imports */
import java.io.File;
import java.util.Iterator;
import java.util.List;

Building a simple java class that implements a listener for our events.

/**
 * This class provides a MATLAB callback to check the spelling of the comments
 * in the code.
 */
public class SpellCheck implements SpellCheckListener {

    private SpellChecker spellCheck; 
    
    /* Method that sets the dictionary */ 
    public void setDictionary(String dictFile) {
        try {
            SpellDictionary dictionary = new SpellDictionaryHashMap(new File(dictFile));
            spellCheck = new SpellChecker(dictionary);
            spellCheck.addSpellCheckListener(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    } 
    
    /* Method to check the spelling */ 
    public void checkSpelling(String inputText) {
        try {
            spellCheck.checkSpelling(new StringWordTokenizer(inputText));
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    } 
    
    /* Event listener goes here */
} 

We have a method to set a language specific dictionary and a method to check the spelling of an input String. The Jazzy library will then fire an event that we act on. The event listener looks like this:

   /* Event listener that populates the suggestions and echo them as necessary */
    public void spellingError(SpellCheckEvent event) {
        String message = new String("MISSPELT WORD: " + event.getInvalidWord()); 
        
        /* Echo to the command prompt */ 
        List suggestions = event.getSuggestions();
        System.out.println(message);
        
        if (suggestions.size() > 0) {
            for (Iterator suggestedWord = suggestions.iterator(); suggestedWord.hasNext();) {
                System.out.println("\tSuggested Word: " + suggestedWord.next());
            }
        } else {
            System.out.println("\tNo suggestions");
        }
    }

The first version of this Java module just echoes the spelling error and suggestions to the Command Window. Compiling the java code and packaging it into a JAR file is usually a single click operation in most Java development tools.

compile:
Building jar: I:\Work\SpellChecker\lib\java\MATLABSpellCheck\dist\MATLABSpellCheck.jar
jar:
BUILD SUCCESSFUL (total time: 1 second)

MATLAB is built on a Java platform so enabling this module was a single line of code to add it to the dynamic java classpath. I had my basic spellcheck in MATLAB in minutes.

javaaddpath('I:\Work\SpellChecker\lib\java\MATLABSpellCheck\dist\MATLABSpellCheck.jar');

Testing it out

To test it out, I downloaded a few sample dictionaries from the JazzyDicts SourceForge repository which contains a wide selection of supported languages. Then, in MATLAB:

% Make Jazzy available to MATLAB
import com.mathworks.spellcheck.*;

% Setup a default language.
dictFile = which('en_USx.dic');

% Create a jazzy spellchecker
obj = SpellCheck();
obj.setDictionary(dictFile);

% Check the spelling of an input string
obj.checkSpelling('Yello Worrld')
MISSPELT WORD: Yello
	Suggested Word: Jello
	Suggested Word: Cello
	Suggested Word: cello
	Suggested Word: hello
MISSPELT WORD: Worrld
	Suggested Word: world

It only takes a few more lines of code to wrap this as an easy-to-use MATLAB class that inspects the contents of my editor.

With that I was able to check-off the requirements for being multi-lingual and easy-to-use. I added common words like MATLAB, etc. to my local dictionary file and continue improving it as I go.

The module itself is less important than the technique that shows one way to extend the MATLAB platform. I decided to keep this post a single, simple example to describe MATLAB's ability to leverage other technologies out there. We plan to talk about how to produce an user-friendly MATLAB interface in the upcoming posts.

In summary, MATLAB's functionality can be complemented and strengthened with 3rd party technologies to provide a single cohesive user experience.

MATLAB can also bring powerful functionality into other platforms, but that is a whole other topic.


Get the MATLAB code

Published with MATLAB® R2015b

11 CommentsOldest to Newest

Yaroslav replied on : 1 of 11
Hi, To tackle this problem, I use VIM—an external editor with a built-in spellchecker (EMACS would do the same). However, it means I must leave the warm-and-cozy MATLAB environment while making these changes. Is there an intention by TMW to integrate a spellchecker to the MATLAB editor? Kind regards
Arvind Hosagrahara replied on : 2 of 11
I will create an enhancement request. I do know that our development team has a long list of exciting features planned for the MATLAB editor but my underlying point was that like vim, MATLAB offers a very mature environment to extend functionality. The idea behind the post is that users do not have to wait for things like this to ship in product as it is demonstrably easy to add functionality and customize the product to suit your needs.
Sam Roberts replied on : 4 of 11
Hi Arvind, On a slightly connected topic (since you'd typically like to spellcheck only the comments in your code), a while ago I attempted to craft a regular expression that, given a line of code, would return text in the line that contained a comment. I'm not great at regular expressions, but it turned out to be much harder than it looked at first sight. So it's easy to find percent symbols, but you need to exclude percent symbols that occur as part of a string (which they commonly do, for example as arguments to sprintf or fprintf). So you can then also find and exclude things between matching pairs of apostrophes. But even that turns out to be not enough, as the apostrophe can also be used to indicate a transpose, and you might have multiple transposes that looked like a pair of quotes. At that point I gave up. Does anyone at MathWorks have a regular expression they could share that can be used to extract comments from a line of code? (Let's not worry about block comments for the moment, I think I can do those separately). Thanks, Sam
Arvind Hosagrahara replied on : 5 of 11
@oleg - I do know that other projects such as the MATLAB-Emacs integration do reach into the mlint infrastructure - this was described a while ago at: https://blogs.mathworks.com/community/2009/09/14/matlab-emacs-integration-is-back/ The MATLAB object wrapper around this code produces an mlint-like textual output detailing the line number (when parsing entire files) and this was sufficient for my basic needs. I do agree that having it integrated into the editor would be nice. I plan to take a closer look at whether integrating into mlint is easy/possible over the next few days.
Arvind Hosagrahara replied on : 6 of 11
@sam - The MATLAB object wrapper that I use does have a switch to inspect only comments. It works off a simple test to see if the entire line is a comment. As you correctly note, to do this robustly for inline comments and block comments is a lot trickier than it initially appears. I took a swing at it but quickly decided to go the other way. Appending a list of common MATLAB keywords/functions to my dictionary allowed me to check the spelling of my variable names in the code and that was useful in itself. In light of my last requirement (#5 - that this example not turn into a huge project by itself), I decided to call it a feature, not a bug! :-) Regular expressions are very powerful but I tend to steer clear of using them for parsing anything other than simple, well-structured content.
Simon replied on : 7 of 11
Hi Arvind, I really like the idea of your application. But somehow I am not able to get it running. I compiled using javac -cp jazzy0-2-1.jar SpellCheck.java and jar cvf SpellCheck.class SpellCheck.jar. After importing this in Matlab I still get the the following error message: Undefined function or variable 'SpellCheck'. Error in testDrive (line 11) obj = SpellCheck(); Why? Thanks
Arvind Hosagrahara replied on : 8 of 11
The error you are seeing can be due to many reasons. I suspect that it is due to using the 1.8 version of the Java compiler. Typing the "ver" command in MATLAB will tell you which Java version MATLAB uses - you can find this information in the header of the output (eg: Java Version: Java 1.7.0_60-b19 ...). You could either try compiling this code above with the matched version of the JDK OR use the -source 1.7 -target 1.7 flags to generate class files for the specific VM version. Please remember to package your class correctly. In my case, I had to use:
> javac -cp jazzy0-2-1.jar SpellCheck.java -source 1.7 -target 1.7 -bootclasspath "c:\Program Files\Java\jdk1.7.0_80\jre\lib\rt.jar"
> copy SpellCheck.class com\mathworks\spellcheck\.
> jar cvf SpellCheck.jar com\mathworks\spellcheck\SpellCheck.class
And finally, please ensure that the jazzy jar file is also on the Java classpath (I omitted writing about this step in the post). This is done in the same way:
>> javaaddpath(fullfile(pwd,'jazzy0-2-1.jar'));