• in

    Fixing Absolute Paths, From Jekyll to Cordova

    Jekyll has really been a great tool to develop a site with. It allows me to take a bunch of content and lay it into templates to generate a static website, with dynamic-like content, that can be served from nearly anywhere. With jQuery Mobile and some JavaScript thrown in, an entire application is easily born. This was the approach I took with the Portland Women's History Trail project. However, my troubles began when working to bundle the HTML5/CSS/JavaScript into an native app with Cordova.

    Jekyll is designed to develop hosted websites, not applications to be deployed with Cordova. When the site is compiled, internal links are generated as is. Meaning no special processing is done to locate things relatively. There is some help for sites not hosted a the root of their domain, in using the site.* configuration, but this is not enough. In order for the site to work when packaged in Cordova all the links must be relative or you have to work out some method or patching them up to the internal location at runtime. Not fun.

    Using a site map, we can look at a specific example.


    In the top-level pages (index.html, trails.html, places.html, and map.html) all is well. Their links to each other and to deeper pages all work with the default Jekyll configuration. That is a link in trails.html referring to the Congress Street Trail gets constructed as trails/congress-street.html.

    The problem crops up in those deeper pages. Using the Congress Street Trail as the example. In trails/congress-street.html the link for the first site is constructed as places/congress-street/c01-curtis-and-sons.html. Phoey. The URL is relative to the top-level of the site.

    Jekyll has a setting in the configuration files to try and accommodate relocation of the site root. This however does not solve the problem as nested pages need to know their relative depth from the site root to make this work.

    Not wanting to complicate the layout (template) pages, I took a stab at solving this with a simple Python script. The essence of it was, for each line in each .html, .css, and .js file

    line = re.sub(r"(href=)(['\"])/(.*?)\2", relrepl, line)
    line = re.sub(r"(src=)(['\"])/(.*?)\2", relrepl, line)

    where replrepl is defined as:

    def relrepl(match):
        if depth:
            fix = '../' * depth
            fix = ''
        return match.group(1) + match.group(2) + fix + match.group(3) + match.group(2)

    I was quite content with this quaint post-processing approach for about 8 hours. Then it hit me, I was fighting the framework that Jekyll provides. I almost always find that if things seem hard or impossible to do within the framework you are working with, your approach is wrong. You are not using the framework how it was designed, you are fighting it.

    The in-framework approach is to use Liquid tags to figure out at what depth the page is and add that many ../'s to the front of problematic URLs. Actually it's cleaner to create a variable (e.g. site_root) that has the right number of ../'s and prepend that where needed. Unfortunately the variable scope in Liquid is very local, so the variable creation code needs to go at the beginning of any file that will use it. Here's a specific example, the project's includable page footer, footer.inc

    {% capture my_lvl %}{{ page.url | split:'/' | size }}{% endcapture %}{% capture site_root %}{% for i in (3..my_lvl) %}../{% endfor %}{% endcapture %}
    <div data-id="footer" data-role="footer" data-position="fixed" data-tap-toggle="true" data-theme="a">
         <div data-role="navbar">
                   <li><a data-tab="trails" href="{{ site_root }}trails.html" data-icon="home" data-transition="fade">Trails</a></li>
                   <li><a data-tab="map" href="{{ site_root }}map.html" data-icon="location" data-transition="fade">Map</a></li>
                   <li><a data-tab="places" href="{{ site_root }}places.html" data-icon="bullets" data-transition="fade">Sites</a></li>

    Note that all hard-coded URLs are prefix-less; they lack a / at their start, making them relative. This is contrary to many of the framework examples. In fact, Jekyll generates page.url with the / prefix. For links to be relative that needs to be stripped off. The following does just that, on a page that lists all the sites associated with a particular trail.

    <ul id="place-list" data-role="listview">
        {% assign trail_places = site.places | where:"trail", page.trail %}
         {% for place in trail_places %}
              <li><a href="{{ place.url | remove_first:'/' | prepend:site_root }}">
                   {{ place.title }}</a>
         {% endfor %}

    Both of these approaches work in either a web-hosted and bundled application. They both make all the internal links relative to the current page. They both appear to function the same. However, the Python version uses a post-processing step that makes the generated product different in the web-hosted and bundled applications. This could easily introduce bugs or currently unseen functional differences that would be difficult to track down in the future. Working with rather than against the framework is the right choice.

  • in

    Maine Campus Crush

    Maine Campus Crush is a tile-matching puzzle video game. It is also a challenge game between the University of Maine System campuses. Choose your team and play for the highest scores!


    • Loading Leaderboard...
    • 0


    • 0


    • 0


    • 0


    • 0


    • 0

      Black Bears

    • 0


    • 0


    • 0



    The objective of this game is to swap one campus mascot tile with an adjacent tile to form a horizontal or vertical chain of three or more tiles of the same color. Bonus points are given when chains of more than three identical tiles are formed and when two chains are formed in one swap. Tiles disappear when chains are formed and new tiles fall from the top to fill in gaps. Sometimes chain reactions, called cascades, are triggered, where chains are formed by the falling tiles. Cascades are not yet awarded with bonus points. There are two variations of the game to choose from.

    Although normally the player gets only three in a row for tiles, sometimes they can get four or five in a row. And in rare conditions, they can get six, seven, and even eight in a row! You get more points for each additional tile that matches.

    The game is over when no more moves can be performed. The score is then compared against others from your campus and, if high enough, ranked on the leaderboard.


    The game is heavily based on Bejewled

  • in

    Portland Women's History Trail

    A mobile, web-based version of the Portland Women's History Trail originally created by Eileen Eagan and Polly Welts Kaufman in Portland (Maine). The app is built using jQuery Mobile and jekyll to create a complete HTML5/CSS3/JavaScript application.

    The app is not complete! We are still working on the content and have engaged a design studio to help with the look and feel.

    prototype screen capture

    Visit the Trail Now

    The content is all markdown and incredibly simple to maintain. Jekyll is used to convert the content to HTML which is then laid into templates for each content type (trail, sites, etc.). With the templates jekyll spits out a completed "application."

    The application is still under development so there are still quirks that need to be sorted out. Navigation within a trail and site is not broken but close. The current design is a bottom tabbed (aka iOS) interface and then has a navigation within each tab.

    The prototype was relatively easy to get up and running in a few hours. It has the features and ideas that make it easy to show others, including non-technical folks. It gives the feel of the design and shows a possible implementation. And, as with any prototype, it needs work.

  • in

    K1N Navassa Island Contact

    I managed to make contact with the "rarest of the rare" remote locations for amateur radio operators this morning, K1N, on Navassa Island. It's a tiny place between Hati, Cuba, and Jamacia. It is administered by the US, but remains disputed between the US and Hati.

    Navassa Island

    From the news and the K1N website, I knew they would be on the radio today. I was hoping they would be on 20m upper sideband (USB) and I was in luck! At 2015-02-07 15:35 UTC I made a brief 5x9 QSO with the 2015 Navassa DXpedition among the huge pileup of others across the world.

    N1SH in the K1N Log

    Now I can sit back and wait for the QSL card and the ARRL LoTW entry. Good luck to the other folks out there trying to get a QSO with them.

    Navassa Island

  • in

    Pondering Site Changes

    Here I sit, looking at past projects (portfolio) and posts thinking of the work that goes into the site versus the work that goes into the content. The result is, too much time goes into the site and not enough into the content. There must be an easier way. A way to encourage myself to write more content and avoid my temptation to tinker with site mechanics.

    There are also numerous places where I maintain some form of content. Some are more regular than others. While they all have their primary goals, I get them mixed up once in a while. And I also purposefully mix them up sometimes, while living on the edge of the life-work balance. I need to sort that out and make it require much less mental energy.

    There are several different chunks of content out there; course materials, past projects, quotes, book notes, development notes, project ideas, publications, and other uncategorised things. Looking at the spread, coming up with a category list might be a great first step.

    Here is my initial category list for articles:

    • development -- general development thoughts and ideas
    • mobile -- development and projects geared towards mobile devices
    • release -- news release type things, products in app stores
    • product -- release product articles, notes, information
    • courses -- related to courses taught or taken (I don't like this tag name)
      • cos450 -- COS 450/540 Operating Systems @ USM
      • cos460 -- COS 460/5?? Computer Networks @ USM
      • cos399 -- COS 399 Programming Autonomous Robots @ USM
      • cos497 -- COS 497 Independent Study @ USM
    • site -- website notes, updates, improvements
    • quote -- collected quotes
    • book -- book notes, taken from Kindle, iBooks, etc.
    • car -- related to fixing vehicles and motors
    • radio -- related to amatuer radio
    • electronics -- electronic projects, hardware
    • games -- related to games, video or otherwise

    Now I need to commit to some next steps to actually get this done. Here, of course, is where I usually fall down. For personal projects I tend not to be very good at following a schedule. It's my project, why should I? So here is a not-schedule but some general ideas on next steps instead.

    • Commit to a template and stick to it.
    • Force content into the template, break projects out where they make sense.
    • Investigate alternate hosting locations ** Github ** Amazon S3 ** Google Sites


    February 7, 2015: Updated to include raido category and clean up the text.

  • in

    COS 399 - Programming Autonomous Robots (Spring 2015)

    Introduction to the programming concepts involved with autonomous robotic systems. Using off the shelf robot kits students will design a simple robotic platform to meet specific goals. Then, using a common platform for the remainder of the course, students will develop their programming capabilities. Simple open-ended, feedback, and artifial intelligence systems will be explored throughout the. Several benchmarks and robot competitions will be used demonstrate the platform and programming learned in the course.

    Course Materials

    The Syllabus is the index to the course this semester and it is located on Google Drive. All the handouts are publicly available, grading and project submission is in the University's learning management system, Blackboard.

  • in

    The Art of Memory by Frances A Yates

    Book notes from The Art Of Memory by Frances A Yates

    The Art of Memory

    You have 20 highlighted passages

    Last annotated on October 1, 2014

    "Noting that it was through his memory of the places at which the guests had been sitting that he had been able to identify the bodies, he realized that orderly arrangement is essential for good memory."

    "order to form a series of places in memory, he says, a building is to be remembered, as spacious and varied a one as possible, the forecourt, the living room, bedrooms, and parlours, not omitting statues and other ornaments with which the rooms are decorated."

    "Cicero emphasizes that Simonides’ invention of the art of memory rested, not only on his discovery of the importance of order for memory, but also on the discovery that the sense of sight is the strongest of all the senses."

    "There are two kinds of memory, he continues, one natural, the other artificial. The natural memory is that which is engrafted in our minds, born simultaneously with thought. The artificial memory is a memory strengthened or confirmed by training. A good natural memory can be improved by this discipline and persons less well endowed can have their weak memories improved by the art."

    "The artificial memory is established from places and images"

    "A locus is a place easily grasped by the memory,"

    "Images are forms, marks or simulacra of what we wish to remember."

    "The art of memory is like an inner writing. Those who know the letters of the alphabet can write down what is dictated to them and read out what they have written. Likewise those who have learned mnemonics can set in places what they have heard and deliver it from memory. ‘For the places are very much like wax tablets or papyrus, the images like the letters, the arrangement and disposition of the images like the script, and the delivery is like the reading."

    "useful to give each fifth locus some distinguishing mark."

    "It is better to form one’s memory loci in a deserted and solitary place for crowds of passing people tend to weaken the impressions."

    "two kinds of images, one for ‘things’ [res], the other for ‘words’ [verba]."

    "‘memory for things’ makes images to remind of an argument, a notion, or a ‘thing’; but ‘memory for words’ has to find images to remind of every single word."

    "When we see in every day life things that are petty, ordinary, and banal, we generally fail to remember them, because the mind is not being stirred by anything novel or marvellous. But if we see or hear something exceptionally base, dishonourable, unusual, great, unbelievable, or ridiculous, that we are likely to remember for a long time."

    "Thus nature shows that she is not aroused by the common ordinary event, but is moved by a new or striking occurrence. Let art, then, imitate nature, find what she desires, and follow as she directs. For in invention nature is never last, education never first; rather the beginnings of things arise from natural talent, and the ends are reached by discipline."

    "We all know how, when groping in memory for a word or a name, some quite absurd and random association, something which has ‘stuck’ in the memory, will help us to dredge it up. The classical art is systematizing that process."

    "virtue has four parts, namely Prudence, Justice, Fortitude, and Temperance."

    "Prudence is the knowledge of what is good, what is bad and what is neither good nor bad. Its parts are memory, intelligence, foresight [memoria, intelligentia, providentia]. Memory is the faculty by which the mind recalls what has happened. Intelligence is the faculty by which it ascertains what is. Foresight is the faculty by which it is seen that something is going to occur before it occurs."

    "‘One must employ a large number of places which must be well-lighted, clearly set out in order, at moderate intervals apart, and images which are active, which are sharply defined, unusual, and which have the power of speedily encountering and penetrating the mind."

subscribe via RSS