Introduction

Since the first version, PubCoder approach to code was that of trying to export clean code and don’t hide it to the final user, though understanding and writing code is an option and not a requirement when using the app.

All PubCoder exports are based on web technologies (one XHTML, one CSS and one Javascript file per page, plus various shared code), and you have many ways of customizing the code or adding more. You can use the Code button in the project window to customize HTML headers, CSS or JavaScript code, both at a project-level and page-level: basically project-level custom code will be included in every generated HTML page.

You can also use Smart Objects to add contents directly to the page DOM: at its core, a smart object is an blank DIV that you can fill with whatever you like, even an iframe. This is the best option to add custom content or embed external content.

Finally, you also have a Run Javascript action that allows you to run custom javascript code as a PubCoder action, so you can combine it with other standard actions in PubCoder’s event/actions mechanism.

Code Editor

The Code Editor in PubCoder is really powerful; based on the widely adopted Ace, it features syntax highlighting for HTML, XML, Javascript and CSS, powerful find/replace with regular expressions, automatic code reindent, matching parentheses highlighting, hidden characters display, text drag and drop, line wrapping, code folding, multiple cursors and selections, live syntax check for JavaScript and CSS and much more.

Code Editor

On the left, it displays up to three panels with snippets, double-click a snippet to append code to the code editor:

  • Snippets: a list of code snippets to quckly add ready-to-use code to include scripts, get objects, trigger events and more
  • Assets: quick access to Assets Library, double-click one to insert a reference to one of the assets in your project
  • Layers: visible only when editing page-level code, it lists all layers in your page, double-click one to insert a reference to an object

On top of the editor, you can find a toolbar with buttons for the various code editor functionalities.

icon Undo the last edit
icon Redo the last edit
icon Comment/uncomment the current selection
icon Re-indents the code
icon Show/hide invisible characters
icon Turn on/off text wrap
icon When editing CSS, opens a window that allows to replace fonts definitions
icon Show/hide the find/replace panel
icon Opens the ACE help page that lists keyboard shortcuts

Finally, when editing XHTML, the editor automatically checks that the code entered is valid XHTML, giving a warning if it is not.

PubCoder Framework In Depth

In this section, we analyze more deeply the code outputted by PubCoder to create your pages and objects, so that you can undestand how to how interact with it using your own code.

Page Structure

For each page, PubCoder outputs a folder containing three files:

/page.xhtml The HTML page file with the page contents
/styles.css The CSS file containing styles for the page and object, eventually including your custom CSS code
/actions.js Javascript file containing framework initialization, code for all interactictivity on the page, and eventually including your custom Javascript code

Here’s an example of the HTML page file for an “Hello World” page made with PubCoder, that is a page containing only a text box saying “Hello, world!”

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:epub="http://www.idpf.org/2007/ops" 
      xmlns:ev="http://www.w3.org/2001/xml-events"
      xmlns:ibooks="http://apple.com/ibooks/html-extensions" >
  <head>
    <meta name="generator" content="PubCoder 3.3.0.970 for OS X" />
    <meta charset="utf-8"/>
    <title>1</title>
    <meta name="viewport" content="width=736, height=414" />

    <!-- import general CSS -->
    <link rel="stylesheet" type="text/css" href="../../css/general.styles.css" />

    <!-- import page-specific CSS styles -->
    <link rel="stylesheet" type="text/css" href="styles.css" />
		
    <!-- import jquery -->
    <script type="text/javascript" src="../../js/jquery.js"></script>
    <!-- more javascripts imports here... -->

    <!-- import actions and page-specific javascript -->
    <script type="text/javascript" src="actions.js"></script>	  		 
  </head>

  <body>
    <div class="SCPage SCPage1" dir="ltr">
      <div class="SCOverlay SCOverlay1">
        <!-- objects in the page overlay will go here -->
      </div>
      <div class="SCContent">
        <!-- page objects will go here, like our "Hello World" text -->
        <div id="obj4" class="SCPageObject SCText">
          <div id="obj4_content" class="SCTextContainer SCTextVAlignMiddle">
            <p>Hello, world!</p>
          </div>
        </div>
      </div>
    </div>
  </body>
 </html>

As you can see the code is very clean & simple: after declaring some namespaces and meta tags, we import the required CSS and Javascript, both generic code and code specific to your page in styles.css and actions.js.

The structure of the body provides a container div for the page, which always has classes SCPage and SCPage<number>, which encapsulates the two layers of your page: one with the contents of the overlay page (in a div with class SCOverlay, which here is empty) and another one, below the overlay, with the actual contents of your page (in a div with class SCContent).

As you can see, inside the .SCContent container we finally have our text object with class SCText.

XHTML vs HTML

Though we often use the terms HTML and XHTML indifferently throughout the documentation, PubCoder pages are actually XHTML files, since this format ensure compatibility with EPUB format and better tooling for code parsing and handling.

XHTML is a family of XML languages which extend or mirror versions of HTML. It does not allow omission of any tags or use of attribute minimization. Basically, XHTML requires that there be an end tag to every start tag and all nested tags must be closed in the right order. For example, while <br> is valid HTML, it would be required to write <br /> in XHTML.

The code editor will warn you if you are writing non-XHTML code, but fixing the issue is up to you, but this should be pretty easy since you often simply need to:

  • Use empty-element syntax on elements specified as empty in HTML, e.g. use <br /> instead of <br> and <img src="path/to/img.jpg" /> instead of <img src="path/to/img.jpg">
  • Include close tags for elements that can have content but are empty, e.g. <div></div>

Container Objects

The HTML code that PubCoder writes for an object is not always “obvious”, in the sense that some objects are directly mapped to their HTML counterparts, like a button object, which is mapped to an html button element:

<button id="obj4" type="button" role="button" class="SCPageObject SCButton">Click Me</button>

…while others are exported using also a “container” object, like the text in the example above, in which the div containing the text paragraphs is encapsulated in a container. This is done for different reasons for each object, for example in the text object we use the div.SCTextContainer node to support vertical alignment of text inside the text box. Here’s how an Image Object is exported instead:

<div id="obj11" class="SCPageObject SCImage">
  <img id="obj11_img" src="../images/obj11_image.jpeg" />
</div>

You may expect to see a simple img tag, while we are actually encapsulating it inside a div.SCImage. This is very important to understand, since some properties like border and shadow settings or CSS classes and styles are always applied to the container labelled with the SCPageObject class, which sometimes incapsulates the real content (e.g. to the div instead of the img).

Please be sure to check manual pages for the various layout objects, widgets and controllers to see an example of how they are exported.

Take this into account also when writing custom css code: if you want to select Image Objects with a myClass CSS class on the page, simply use .SCImage.myClass, to select the img tag of Image objects with that CSS class, use .SCImage.myClass img instead.

Custom HTML Headers

PubCoder allows to add custom HTML headers, both on a page-level and project-level: just click the Code button in the project window and select Page ▹ HTML HEAD or Project ▹ HTML HEAD to open the Code Editor and add headers that will be appended to the head element of the current page or of every page, respectively.

HTML Headers are the right place to import external scripts or CSS files. The Code Editor also gives you snippets to easily add import tags and scripts definitions in the right way.

Custom CSS Code

PubCoder allows to add custom CSS styles definitions, both on a page-level and project-level: just click the Code button in the project window and select Page ▹ CSS or Project ▹ CSS to open the Code Editor and add styles definitions that will be appended to the page style.css file of the current page or of every page, respectively.

Custom CSS allow to define styles that you use throughout you page or project. Two snippets in particular are useful to add Character and Paragraph styles that, once defined, will appear in the Text Editor’s Styles menu so that you can apply them to your text.

Paragraph styles are applied to entrire paragraphs, namely p tags; here’s an example of a paragraph style that increments paragraph spacing and sets a small-caps style to the entire paragraph:

.SCText p.MyParagraphStyle {
  margin-bottom: 10px;
  font-variant: small-caps;
}

Character styles, instead, can be applied to whatever portion of text, namely span tags; here’s an example of a character style that makes text red and underlined with a dotted line:

.SCText span.MyCharacterStyle {
  color: red;
  border-bottom: 1px dotted red;
}

Another example of a useful character style, is one that will make an inline image in the text float to one side so that text can flow around it, you can define a style like this and assign it to an inline image in the text editor like you would assign a style to any other portion of the text:

.SCText span.Float-Left {
  float: left;
}

Another important thing that you can set using a custom CSS snippet is a special style for the Read Aloud functionality, here’s an example of one that will animate and enlarge word highlighting:

.-epub-media-overlay-active,
span.-epub-media-overlay-active,
span.-epub-media-overlay-active > span {
  border-radius: 6px;
  transition: .1s ease-in-out;
  -webkit-transition: .1s ease-in-out;
  -moz-transition: .1s ease-in-out;
  -o-transition: .1s ease-in-out;
}

Last but not least, you can define custom CSS classes and apply them to the various objects in your page using their CSS Classes property.

Custom Javascript Code and pubcoder.js

PubCoder allows to add custom javascript, both on a page-level and project-level: just click the Code button in the project window and select Page ▹ JavaScript or Project ▹ JavaScript to open the Code Editor and add JavaScript code that will be executed when the page loads.

As you may already know, this is not the only way to add JavaScript code, since you can also add it in Smart Objects or execute custom code via actions using a Run Javascript action, but this is probably the best place to insert initialization code or definitions that you use throughout your page or project.

PubCoder bundles JQuery with your publications, so you can use it to get objects and interact with them. Just double-click a row on the Layers panel at the right of the Code Editor to append a snippet to get a reference to the object, for example in the following animation you can see how to build a script to trigger the Tap event on a button without directly typing any code:

JavaScript Snippets

Another way of referencing objects via code is defining an Alias for the object in the object inspector. An alias is a mnemonic identifier specified by the user, to be used as an alternative to the numeric object ID. If an object has alias “MyObject”, you can access its DOM element using pubcoder.objects.MyObject or via JQuery using $(pubcoder.objects.MyObject). Aliases can contain only letters, numbers and the _ (underscore) characters, and must begin with a letter.

Aliases can also be defined for pages, this is very useful to obtain the URLs of the various pages (you can find them in pubcoder.pages.MyPageAlias) and when you add code to the overlay page that must discriminate between the various page (pubcoder.page.alias always contains the alias of the current page)

The pubcoder object also offers various library functions that you can use to trigger PubCoder events and actions from code and a lot more. We call this library pubcoder.js, and we’re continuously improving this adding new features. Here’s a list of functions that can be accessed using pubcoder.functionName where functionName is one of the following:

alert(alertTitle, alertText) Display a message to the end user, over the content of your page
page.alias Returns the alias of the current page.
page.title Returns the title of the current page.
page.number Returns the number of the current page.
pages.MyPageAlias Returns the URL of the page with alias MyObjectAlias. The returned URL is relative to the current page.
objects.MyObjectAlias Returns a DOM element for the object with alias MyObjectAlias. Use $(pubcoder.objects.MyObjectAlias) to obtain the corresponding JQuery object instead.
getObjectWithId(obj) Returns the JQuery object for the page object obj. The parameter can be in the format "obj4", "#obj4" or $("#obj4"), and this is true for all other pubcoder.js methods taking an obj parameter
getObjectsWithClass(className) Returns objects labeled with CSS class className
getPageObjectsWithClass(className) Returns objects labeled with CSS class className in your page (thus excluding objects in the overlay layer)
getOverlayObjectsWithClass(className) Returns objects labeled with CSS class className in the current overlay page
bringPageObjectToFront(obj) Brings page object obj to the front layer
bringPageObjectForward(obj) Brings page object obj one layer up
sendPageObjectBackward(obj) Sends page object obj one layer back
sendPageObjectToBack(obj) Sends page object obj to the back layer
bringPageObjectToInitialLayer(obj) Sends page object obj back to its initial layer
getCounterValue(obj) Returns the current value for the counter obj
switchText(obj, newText) Applies a new text to the text object obj
goToPage(pageNumber) Navigates to page pageNumber in the publication
openUrl(url, openInBrowser) Opens web address url. When exporting a native app or an XPUB file, if openInBrowser is true, the url will be opened in the device browser, otherwise it will be opened in the reader app

Using Action Lists to invoke PubCoder actions from code

Action lists are controller objects that allow to define a list of actions. You can use a single line of JavaScript code to trigger the Run event of an action list, thus executing its actions from your custom script.

Let’s say you have an action list on your page with ID #obj33, you can run it in JavaScript code using this command (look for the snippet Trigger Event Run Action List in the code editor):

$("#obj33").trigger(PubCoder.Events.Run);

This will execute actions in the Run event of the action list, immediately returning control to your script. You can see a more complex example in this article on Inside PubCoder, where this technique is used to achieve the following effect:

scrolling