Now that you understand the DOM and know how to create XPaths (directions) you've got to learn how to put it all together into a translator. For that, you've got to learn how to write a little JavaScript.
Learning a computer language is largely just a matter of learning all of the components the language has built into it, and learning how to combine those components in various combinations to achieve what you want.
The first thing you need to know is that JavaScript and Java are two totally different languages. If you are trying to learn JavaScript, you cannot follow instructions intended for Java. The best way I've seen this explained is:
"Java is to JavaScript as car is to carpet."
They're completely different and you do not need to know any Java to write a Zotero translator or to learn JavaScript.
Comments in code help human readers understand what the code is supposed to do. They are also helpful to remind you what your code is supposed to do if you come back to it a month (or a year) later.
You learned in Chapter 4 that <!–– This is an HTML comment. ––>
In JavaScript, single line comments are written following two slashes.
Example 6.1
//This is a JavaScript comment.
Do not confuse this with XPath syntax, which uses two slashes for a different purpose.
A comment that takes several lines is written:
Example 6.2
/* like this. Starting with a single slash followed by an asterisk and
then finished by an asterisk and a single slash. */
You could technically use the symbols for a multi-line comment if you only have one line of code, but it takes longer to type.
This guide will be using JavaScript comments from time to time to explain parts of the code.
Ok, let's learn some JavaScript!
Computer programming can seem complicated when you are first learning a computer language. Most guides teach a bunch of different concepts and you are left to your own devices to put them together, wondering if there is something else out there you have not yet learned. In an effort to prevent that, here is an oversimplified explanation of the major components in JavaScript:
Computer programs are built from five basic building blocks, which each have many variations and can be put together in infinite combinations. In JavaScript, Variables hold information. Methods can change that information in almost any way imaginable. You can use Statements to test if variables meet certain criteria. Loops do the same thing over and over as many times as you want and Functions re-use chunks of code that you have already written, rather than rewriting them.
Your translator will essentially be a Function that contains Variables holding different pieces of bibliographic information. You obtain this information by scraping it off a webpage with XPaths (another type of variable). You will use various Loops, Statements and Methods to organize and then save that information into Zotero.
Warning: when writing computer code, it is best to do so using a program designed specifically for that purpose. You might be tempted to use your favourite word processing program, but this can lead to some annoying problems. For instance, to a computer there is a marked difference between “, ” and ". JavaScript requires the " character or else errors will occur. Programs such as MS Word use “ and ” by default. If you find yourself getting an error "SyntaxError: illegal character in parsing" take a look at your code and see if you've made this mistake.
To prevent this, the best programs to use for writing your code are Komodo Edit, Notepad++, Notepad, Text Editor, or best of all, Scaffold. In these programs you will be unable to accidentally type the offending characters.
The best way to learn something is to try it. And the best place to try it is the place you're going to be using it when writing your translator: Scaffold.
Open a new window of Firefox and go to the Sample 1 page. Under the "Tools" menu of that Firefox window, select "Scaffold".
Note: Only the window that you launched Scaffold from will respond to Scaffold. If you have many instances of Firefox running at once, you will have to keep track of which window is which. Best to keep one window open if possible. If you close Firefox, you will also have to close Scaffold, reopen Firefox and re-launch Scaffold to get the program to respond properly.
You are going to create a new translator to learn JavaScript. It won't be a real translator, just a testing pad. Fill in the following information into Scaffold. (Ignore the Translator ID: box. This number will be different every time you launch Scaffold).
Label: Learning JavaScript
Creator: Your Name
Target: /member-projects/zotero-guide/
Fig 6.1: Fill in the First Tab as above.
Make sure you are still at the Sample 1 page and then click the Test Regex button to see that you typed the address in properly. If you did, you should see ===>true<===(boolean) in the Test Frame window. If not, check your spelling in the target box.
Click on the "Detect Code" tab. You now have a blank area to test your code.
Let's take a closer look at the first of the five building blocks of computer programming: Variables.
The first thing to do when using a variable in JavaScript is to declare it. This lets the program know what type of variable you are using and what it contains. Imagine you were out for coffee with a friend, who out of the blue started talking about "Snargles," without first explaining what a "Snargle" was. The conversation would not make much sense; this is much the same in JavaScript. If you do not declare the Variable before you start using it, the program will have no idea what to do with it and will send you a bunch of error messages.
To declare a Variable, you type var followed by the name you want to give your Variable and the value you want to give to it. If you wanted to declare a Variable named "Adam" that would hold the value of 1, you would do so like this:
Example 6.3
var Adam = 1;
This is a very simple Variable declaration. Anytime you use "Adam" in your code, the program will replace "Adam" with 1 in its calculations.
In computer programming, Variables work much the same way they did back in math class. The variable x, for example, can hold just about any value you want it to. When you use x, you replace the symbol with the value you have attached to it and perform your calculation. That's pretty much how it works in JavaScript too.
A Variable is a container. It holds a value in the computer's memory, which you can access with your program. In your translator, Variables are what hold your bibliographic information and you then pass the contents of those Variables to Zotero. Variables come in three different types, which serve different purposes.
Types of variables:
Example 6.4
Simple Variable | Array | Object |
x=3; | x[0] = 3; | x[colour] = "blue"; |
y = "p"; | x[1] = 1; | x[size] = "small"; |
x[2] = 29; | x[creator] = "Volvo"; | |
x[3]= 7; | x[date] = 1984; | |
x[n] = "abc"; |
Simple Variables can hold one value. When this piece of information is changed, the previous value is lost forever.
Think of it as a box with a label on it.
Before you can use a simple Variable, you must declare it. This allocates a part of your computer's memory for that Variable.
As you learned just learned, a simple Variable is declared like this:
Example 6.5
var myVariable = myValue;
The prefix, var tells JavaScript to expect a new variable name.
The semi-colon tells JavaScript this line of code is finished. All lines of JavaScript that do not include an { or } must end in a semi-colon.
Simple Variables are useful when you need to make calculations or to keep track of how many times something has happened (Loop iterations).
Try creating a Variable in Scaffold. Give it any numerical value.
Example 6.6
var myVariable=4;
On the next line, type:
Zotero.debug(myVariable);
Make sure you substitute "myVariable" for the name you gave your Variable. Then click the button (Execute). You should see something like this:
Example 6.7
12:00:00 ===>4<===(number)
12:00:00 detectCode returned type "undefined"
Fig 6.1: Fill in the First Tab as above.
The first six digits in the above example are the time. What follows is the contents of the Variable. Checking the contents of the Variables in your code, since normally that information is not visible, is part of a process known as debugging. Debugging is the most important skill you will learn in computer programming. Using the Zotero.debug() method does not affect the program in any way, but it lets you figure out where your program might be going wrong. In complex programs it is very difficult to keep track of what value is contained in every Variable, especially in translators where values in Variables often change. Comments are also crucial when trying to solve problems with your code. If you "comment out" sections of code that have not yet been perfected you can prevent the program from running the lines and help narrow down where problems may be occurring. This saves a lot of time as you do not need to completely remove code that you might need once you figure out the problem using Zotero.debug(). You will probably use Zotero.debug() often when writing your translator to make sure that the correct information is getting to where you want it to go.
Ignore the second line of output for now. It just tells you that your translator isn't working, which is not surprising since you haven't written one yet.
Arrays are like lists. All the items belong to the same numbered list. Like a simple Variable, if you change any value held at a particular spot in the array, the previous value is lost forever.
You define an Array as follows:
Example 6.8
var myArray = new Array();
There are three ways of putting values into an Array. You can do so when you first declare the array:
Example 6.9
var myArray = new Array(12, 4, 1, 93, 18);
or you can do so after the Array has been created:
Example 6.10
var myArray = new Array();
myArray[0] = 12;
myArray[1] = 4;
myArray[2] = 1;
myArray[3] = 93;
myArray[4] = 18;
Both methods will create the exact same Array.
You need not do this in order. The following will also create the same Array.
Example 6.11
var myArray = new Array();
myArray[2] = 1;
myArray[4] = 18;
myArray[1] = 4;
myArray[3] = 93;
myArray[0] = 12;
Finally, you can "push" a value into an Array which will tack it on to the end of the Array. This will only work with an Array. You cannot "push" a value into a Simple Variable or an Object.
Example 6.12
myArray.push(3);
Practice:
Create an Array in Scaffold and debug it to see the contents.
Example 6.13
Zotero.debug(myArray);
If you are only interested in the contents of a certain entry in the Array, you can debug it like this:
Example 6.14
Zotero.debug(myArray[3]);
This will return:
Example 6.15
12:00:00 ===>93<===(number)
Please note that the index of the Array's first entry is 0, not 1. This is important to remember when you go to use the values held in the Array. If you choose the wrong entry, you will end up with unexpected results.
To change one of the values, simply reassign a value:
Example 6.16
myArray[3] = 71;
Arrays are useful when you want to apply the same lines of code to different values. For example, you could write code that would add ten to an item in your Array and then proceed to do the same to every other item in the Array. This can save you a lot of work and make your code much shorter — which is ideal.
Objects are a lot like arrays, except instead of having numbered values they are named, by you. This is like a real object that has properties. A car for instance:
Unlike an Array, the terms are not numbered and the order is not important. Rather, a name, consisting of a set of characters or letters, known as a String, is used instead. You can assign just about any name you can think of to the values. Strings are always enclosed by single or double quotation marks (more on this later).
You define an Object like this:
Example 6.17
var myObject = new Object();
You put values into an Object much like you do with an Array.
Example 6.18
myObject['Colour'] = 'Black';
myObject['Maker'] = 'Ford';
myObject['Year'] = 1912;
myObject['Mileage'] = '50 MPG';
myObject['Tires'] = 'All Season';
myObject['Upgrades'] = 'Elaborate Hood Ornament';
To avoid errors, make sure you do not include spaces in the names. Values can have spaces, but names cannot.
Try to debug your Object as you did in the previous examples. Can you figure out how to debug only the 'Mileage' category?
Objects are very handy for making translators, as it allows you to associate an attribute with a value. This makes the code much more intuitive and makes it easier to keep track of Variables. You can add a ['Publisher'] type to your Object and put the name of your entry's publisher in that part of the Object. You then will be able to remember exactly what Zotero field to save this information to later.
What you name your Variable is largely up to you. You should always try to name your Variable something meaningful. This is important when you have several Variables changing at once; knowing what each is for is crucial to making sure they all do what they are supposed to.
In the Example 6.5, "myVariable" is a rather non-descript name.
Your Variable name can include any combination of letters, digits and underscore characters ( _ ), but cannot begin with a digit or include spaces. Zotero developers use a system of Variable naming known as camelCase. In this system, Variables are made up of meaningful words that help other developers understand what the Variable does. Each new word is begun with an upper-case letter to improve readability. For instance, a variable named caseandpoint is not quite as easy to read as caseAndPoint. When writing your translator, it is good practice to always adhere to camelCase when naming Variables and Functions.
There are a few other words you can't use when naming Variables. These words belong to a list of reserved words that are part of JavaScript's language. These words have special meanings and are off-limits for Variable names. They include words used for coding, such as:
Example 6.19
If
And
While
For
You can always reference the entire list of reserved words to avoid conflicts.
For your purposes, there are two basic types of values that you can give your Variable: Strings and Numbers.
A String is essentially a series of characters that computers regard as text. They can include any combination of keystrokes, special characters or digits. Strings do not have any meaning to the computer; the computer does not even attempt to interpret meaning from a String. You will not offend your computer by using the String "You are a stupid computer."
Strings can include digits, but the digits lose any numerical properties they may have had.
To create a String, you simply enclose your text between two quotation marks or two apostrophes.
Example 6.20
"This is a string"
'this is also a string'
"this is an error' //Quotation mark to start + apostrophe to end = wrong.
"4" //This is a string.
'' //This is a string too!
"Even 9.20#mJW_+ this is a string" //Different character types are ok.
If you need to include quotation marks or apostrophes in a String, you would do so like this:
Example 6.21
"Jim looked for the 'Welcome' sign."
'Jim looked for the "Welcome" sign.'
If you forget to match the quotation marks and the apostrophes, or if you use two sets of either, and write something like this:
Example 6.22
"Jim looked for the "Welcome" sign."
what you are really doing is telling the program that you have two Strings and some meaningless letters in between. The program will interpret this as:
Example 6.23
"Jim looked for the "
Welcome
" sign."
When you go to execute your code, this will produce an error:
Example 6.24
"SyntaxError: missing ; before statement in parsing code."
If you see this error, chances are you have mixed up your quotation marks somewhere. If you cut and paste your code into Komodo Edit or another JavaScript Syntax checking program, it should help you narrow down where the problem is occurring.
Note: JavaScript always stops running at the first sign of an error. Even if you have multiple errors, the code will only tell you about the first one the program encountered. Once you have fixed this first error you can execute the code again and work on fixing the next error — if there is one.
A Number can only contain digits and can be used in a wide range of mathematical formulae. It is possible to use decimal numbers (known as floating point numbers), but you are not going to be doing any complex math to make a Zotero translator. For your purposes, integers (whole numbers) will suffice. Numbers are written much like Strings, minus the quotation marks.
Example 6.25
9 //this is a number
"9" //this is a string.
There are other types of variables, but for now this is all you will need to know to get started.