Hardscrabble 🍫

By Max Jacobson

See also: the archives and an RSS feed

reroute

June 9, 2013

I don’t know how you’re supposed to redirect from old sites to new ones but I did it with a simple Sinatra app. I disconnected the previous sinatra app from my domain and connected this and it kinda works!

require 'sinatra'

get '/' do
  redirect "http://maxjacobson.github.io"
end

get '/feed' do
  redirect "http://maxjacobson.github.io/atom.xml"
end

get '/~about' do
  redirect "http://maxjacobson.github.io/blog/about"
end

get '/~projects' do
  redirect "http://maxjacobson.github.io/blog/about"
end

get '/:anything' do
  redirect "http://maxjacobson.github.io"
end

edit November 2014: I open sourced the app and made a few small tweaks to reflect my current internet home.

welcome

June 9, 2013

I deleted my old blog. I set up some redirects from there to here. I took those old posts offline. Valar blog morghulis.

This one is on Octopress. It is with some small regret that I am killing off Beefsteak.

Doing my prework

June 2, 2013

School starts soon, so I’m cramming my homework in.

Internet Basics

The Web

The Command Line

SQL and Databases

Hypertext Markup Language

Cascading Style Sheets

Git: Version Control

Programming

Basics

JavaScript

Ruby

Rails

Advanced Topics

Testing

Best Practices

loving websites

April 22, 2013

I was sad when I read that Google Reader was ending and I want to examine that emotion. I love Google Reader. I also love Twitter and I’d be sad if Twitter stopped existing.

Except I don’t love either, really. I love the people I follow on Twitter. I’m grateful for Twitter connecting them to me the same way I’m grateful for Google Reader making it possible for me to keep track of the feeds that matter to me. Unlike the people they connect me to, neither service is wholly original or irreplaceable.

I’m ambivalent about Twitter, Inc. but I do love twitter.

I think this happened yesterday but I was very exhausted and I’m not sure: I had brunch with, among others, Harry Marks and Dalton Caldwell. Ostensibly, it was an open ADN meetup, but as one of only six guys around a table, I felt a bit like I was eavesdropping. Today Marks wrote a post about why he prefers ADN to Twitter, and it touches on some of the things we discussed yesterday. It’s a better post than the one that inspired it, which made a similar but poorly elucidated point. In that one, Ben Brooks champions ADN’s exclusivity and compares it to being a member of a private golf course, where “you can play several holes without seeing another soul.” As nice as that may be, it’s an ugly and ridiculous thing to want from a social network. Marks reframes this idea:

App.net is as inclusive as you can get because it puts users and developers first, not big-name companies and celebrities. App.net treats its user base as more than just one big antenna for ads and there are actual support channels that don’t end in .py. That means a lot to me.1

While I’m sure ADN would actually be thrilled if some celebrities used it, I think Marks has a good point that the only people who are being willfully excluded from the network are advertisers and spammers2, and that’s a good thing. I’m not yet sure that I love ADN but I get the sense that it loves me3, at least more than Twitter does. And not just me; it’s got a crush on people, and like most of my crushes, people don’t even know ADN exists.

  1. Does Twitter offer support channels that are python scripts…? 

  2. same thing? lol snap, makes you think 

  3. That’s a very ridiculous thing to say but the founder did pay for my oatmeal yesterday 

back to school

April 4, 2013

So I’m migrated and making plans for the future. The main part of the plan is to go to Flatiron School and get really good at Rails. Other parts include having my tonsils removed to ease my sleep apnea, sclerotherapy to zap the knots of veins weighing down my face, and a wisdom tooth out, possibly all in one surgery. It’s been eight years since my last treatment. I remember afterwards, when the swelling was gone, not recognizing myself. It’s been eight years since my last face scrambling and that’s long enough that I hardly recognize myself again. Some guys have the discipline to get a haircut every three weeks; maybe it’s a standing appointment, maybe it’s a reoccuring calendar entry. My hair graph slopes up as I don’t think about it then roller coasters down every few months. Same as my fat lip, which slowly grows over the years and eventually needs dealing with. I’m not afraid of doctors or hospitals but whenever I spend time around them I find myself marveling at, like, the modularity of diagnostics, and whether that’s amazing and weird or just amazing. Each doctor has a specialty they’re real good at fixing, almost like an assembly line worker, and you feel like an elephant bouncing between blind men (neither analogy is fair at all). Learning to write code establishes a context for clarity that I want to fit everything into, but bodies aren’t computers and neither is The Universe. Least clear of all, probably, is this blog post. I’m tired and anxious and it’s the middle of the night and Art Brut is singing, “The record buying public shouldn’t be voting!” and that helps, but only so much. So I’ll try to sleep. I’ll finish smashcut. I’ll eat lentil soup and I’ll tutor people. I’ll go back to school.

migrations

March 23, 2013

A few days ago on ADN I noticed tech blogger Harry Marks complaining about his blog host, Squarespace. For various reasons, he wanted to take his blog elsewhere. What they gave him was as a large xml file with more than sixty-thousand lines of bracketed stuff amounting to 5.5mb, which is kind of humongous for a text file.

I get uncomfortable when people are upset and I want to help them so I can relax again, so I offered to help convert that xml file into the format he wanted, which is a markdown file for each blog post with the metadata at the top in the YAML front-matter syntax. I felt pretty comfortable that I could help because some of the projects I’ve done recently involved xml interpretation1, markdown2, and general string manipulation, and was like mad bored and jonesing for a project just like this, to do like my mom does Sudoku (which I’m terrible at).

On ADN it’s customary to join conversations uninvited. People go to the global feed and just reply to things. Some apps de-prioritize the global feed, to the ire of these people. My instinct is to give people space, but when in Rome, … write unsolicited programs … ?

So I made this thing and I think it was useful. Marks seems to have successfully migrated his site to a markdowny platform. I felt proud to get a shout out in his anouncement post. I put the converter on GitHub in case other people want to use it: flee to md. But my mind is preoccupied with another migration. I’m moving at the end of the month. I’ve lived in this apartment in Washington Heights for two years now and now I’m going to find out what’s next. Today I crossed a river to New Jersey to tutor a stranger in JavaScript and jQuery and got some cash out of it. It’s hard to know if you’re spending your time well. I don’t find it helpful to think about the cosmos. Yes, life is insanely short and we should cherish every moment. Yes, yes, yes. Of course. And yes, you’re allowed to have hobbies. And yes, it’s counter-productive to become paralyzed by the pressure of cherishing moments, and yes

  1. like souffle which either is way less relevant now that google reader is shutting down, or way more so? not sure. 

  2. like, w/r/t this blog engine. 

devblog

March 19, 2013

Note: When I was first learning Ruby in late 2012, I made a small web app called “beefsteak” to act as my blog. I wrote several posts on that blog while I was exploring and adding features. I’ve since migrated my personal blog away from beefsteak and to Octopress, and then Jekyll. I decided to collapse those posts into one post because I think they’re kind of confusing now that they’re on a Jekyll site. I’m writing this note on July 10th, 2016. By the time you’re reading this, who knows what the blog is running on…

testing this little devblog thing

Originally posted December 1, 2012

So it’s like 6am and I guess I just made my first mini markdown blog engine.

I’m almost certainly too quick to congratulate myself. It has approximately zero features but it’s succeeding at putting HTML on the screen and I call that a win.

This is pretty much the whole app:

require 'sinatra'
require 'kramdown'

get '/' do
  @title = "devblog - max jacobson"
  the_html = String.new
  the_html << "<h1>#{@title}</h1>\n\n<hr />"
  posts = Dir.entries("posts")
  posts.each do |filename|
    if filename =~ /.md/
      the_text = File.read("posts/" + filename)
      the_html << Kramdown::Document.new(the_text).to_html + "<hr />"
    end
  end
  erb the_html
end

get '/css/style.css' do
  scss :style
end

It just checks all the files in a directory called “posts”, checks all of the ones with the .md file extension, and then renders them all one after the other. That’s it!

I wrote this in just a minute or two so I’ll be sure to add more blog-like features to this. Maybe design it up a bit. That mention of sass is more or less for show.

I feel smart right now so I’m comfortable admitting that I’d love to use Jekyll but just can’t figure out how the hell it works.

This is not one of those smartly static sites. It generates each page as you load it. Probably pretty fast, but still, not smart-smart.

Already with the updates

Originally posted December 1, 2012

There are already updates wow I am good.

Things I’ve added in the last small amount of time:

  • a config.rb file for helper methods that get the blog title and subtitle
    • so nothing in the main app file, web.rb is hardcoded and theoretically someone else could use this
  • permalinks based on the file name
  • option to see the markdown source of any page with a little link at the bottom. (alternately just add the .md to any page)
  • some small amount of style, mainly to do with displaying codeblocks
    • incidentally, I’m treating markdown source as “code”

Here’s what the tree of my project directory looks like right now:

[~/Dropbox/Sites/devblog] [maxjacobson] [07:41 AM]
ϡ tree
.
├── Gemfile
├── Gemfile.lock
├── Procfile
├── config.rb
├── posts
│   ├── 2012-12-01-already-updates.md
│   ├── 2012-12-01-gem-anxiety.md
│   └── 2012-12-01-the-first-post.md
├── views
│   ├── layout.erb
│   └── style.scss
└── web.rb

2 directories, 10 files

Off topic, but: I learned how to customize my bash prompt earlier today and that’s what it looks like.

added sorting

Originally posted December 1, 2012

I have added sorting and so I believe the posts on the homepage will be in the proper order. Kewl.

did i just implement search in like 5 minutes?

Originally posted December 1, 2012

I’m not sure but I think I just implemented search like it was no big deal.

It works well and fast but only because there are so few posts, I assume. I’m not searching the whole internet here or anything, but I do kinda feel like I Am Google or something.

That’s a theme for this system: it will get worse the more I use it. I’m kinda excited to ruin it.

man, sorting is hard when you use the twelve hour clock

Originally posted December 1, 2012

I have a TextExpander snippet for quickly inserting the current time. I write ttime and it inserts, say, 10:43 PM. In that format. If it were an hour earlier, it would say 9:43 PM. No leading zero.

This is what was screwing up my sorting method.

I want posts to be sorted based on both date and time, so if there are multiple posts in a day they’ll show up in the right order instead of just alphabetically.

I could have just written those leading zeros manually or I could’ve just used a twenty-four hour clock, but I like my snippet how it is and want my code to come to me rather than the other way around.

So I’ll share my method because I’m sure in as little as a month I’ll find it embarrassing and that’s very fun for me, being embarrassed.

The argument for this method, to_sort, is an array of hashes that stores all of the posts.

Each hash looks like this:

{
  :text=>"the body of the post (in markdown) would go here, but it would be long so I'm leaving it out",
  :title=>"Introducing myself to the command line",
  :date=>"2012-02-26",
  :time=>"12:00 PM",
  :category=>"coding",
  :tags_array=>["command-line", "learning"],
  :filename=>"2012-02-26-introducing-myself-to-the-command-line"
}

And the method takes the info, specifically the date and time, and adds an additional parameter, :sorter, and then sorts the array based on that value of each hash, and returns the sorted array.

def sort_posts (to_sort)
  to_sort.each do |post|
    the_date = post[:date]
    the_time = post[:time]
    if the_time =~ /AM|am/
      if the_time =~ /^[0-9]:/ # aka ONE digit before the colon
        sorter = the_date.gsub(/-/,'') + ("0" + the_time).gsub(/:| |AM|am/,'')
      else
        sorter = the_date.gsub(/-/,'') + the_time.gsub(/:| |AM|am/,'')
      end
    end
    if the_time =~ /PM|pm/
      if the_time =~ /12:/
        sorter = the_date.gsub(/-/,'') + ((the_time.gsub(/:| |PM|pm/,'')).to_i).to_s
      else
        if the_time =~ /^[0-9]:/ # aka ONE digit before the colon
          sorter = the_date.gsub(/-/,'') + ((("0" + the_time).gsub(/:| |PM|pm/,'')).to_i + 1200).to_s
        else
          sorter = the_date.gsub(/-/,'') + ((the_time.gsub(/:| |PM|pm/,'')).to_i + 1200).to_s
        end
      end
    end
    post[:sorter] = sorter.to_i
  end
  to_sort.sort! { |a,b| b[:sorter] <=> a[:sorter]}
  return to_sort
end

So that’s that.

Edit (2012-12-02, 10:58 AM): There’s a bug in there! posts at 12:15am would sort newer than posts at 1:15am becuase twelve is a higher number than one. So I added some conditioanls to treat 12 like zero. Updated code below:

def sort_posts (to_sort)
  to_sort.each do |post|
    the_date = post[:date]
    the_time = post[:time]
    if the_time =~ /AM|am/
      if the_time =~ /^[0-9]:/ # aka ONE digit before the colon
        sorter = the_date.gsub(/-/,'') + ("0" + the_time).gsub(/:| |AM|am/,'')
      elsif the_time =~ /^12:/
        sorter = the_date.gsub(/-/,'') + ("00" + the_time).gsub(/:| |AM|am|12/,'')
      else
        sorter = the_date.gsub(/-/,'') + the_time.gsub(/:| |AM|am/,'')
      end
    end
    if the_time =~ /PM|pm/
      if the_time =~ /12:/
        sorter = the_date.gsub(/-/,'') + ((the_time.gsub(/:| |PM|pm/,'')).to_i).to_s
      else
        if the_time =~ /^[0-9]:/ # aka ONE digit before the colon
          sorter = the_date.gsub(/-/,'') + ((("0" + the_time).gsub(/:| |PM|pm/,'')).to_i + 1200).to_s
        else
          sorter = the_date.gsub(/-/,'') + ((the_time.gsub(/:| |PM|pm/,'')).to_i + 1200).to_s
        end
      end
    end
    post[:sorter] = sorter.to_i
  end

  to_sort.sort! { |a,b| b[:sorter] <=> a[:sorter]}
end

SEE?? Embarrassing. I love it. I’m sure there’s an easier way to do this. But it’s interesting, I think, that an idea (“hmm, i want to sort by both date and time, so why don’t I make a :sorter variable that takes those two strings and combines them into one an integer that represents when it was posted”) morphs and grows into this 28 line mess. I guess it’s time to refactor.

categories and tags

Originally posted December 1, 2012

I added some functionality for categories and tags. The difference between categories and tags, in my implementation, is that there can only be one category, but there can be a bunch of tags.

So be generous with your tags.

You can use spaces in your categories and tags and they’ll be converted to hyphens. They’re comma-delimited.

You can see the tags at the bottom of this post and you’ll see some hyphens. but if you look at the markdown source, you’ll see some spaces.

(You can see the markdown source by clicking the link at the bottom of each post or by simply replacing the / with .md at the end of a post url)

RSS is hard to implement and I’m not sure I’m doing it right

Originally posted December 1, 2012

I’m pretty sure I’m not doing this right but I’ve added an RSS feed so that’s fun, enjoy.

It’s available at /feed and ever time that “file” is queried, the sinatra app will generate an up-to-the-minute accurate feed, including all of the posts.

I don’t necessarily recommend subscribing because I might change where it’s located soon. Right now the blog is online at http://devblog.maxjacobson.net but I may move it to blog. or beef. or beefsteak. or something else entirely.

going open source

Originally posted December 2, 2012

Just for fun I’m sharing the source code for this blog in full on github. I don’t know if anyone else will or should use this but maybe they’ll want to and I won’t stop them.

It’s surprisingly easy having two remote destinations for this code (heroku, where my blog is hosted, and now github where the source code is hosted). I make changes, commit them, push to one, then push to the other. Easy peasy.

If someone else wants to use it, they’ll have to delete my stuff and replace it with their stuff. I’m not giving them a blank slate. Because I’m not sure how to maintain two separate versions like that. But they’ll figure it out, I think.

I guess I’ve been planning to do this, because I’ve refrained from hardcoding my information (name, blog title, etc) into the code. Instead it’s in a separate config.rb file (which you can see on github).

I’m cold on this balcony in San Diego. I am proud that I made this in like two days. I will keep working on it. A small part of me just got a tingling urge to hurl my laptop down into the parking lot like it’s my punk rock guitar.

I’m worried that it will be a whole hassle if I ever want to change the address of this blog. I already kinda feel limited by “devblog”.

Right now my Top Level website, http://maxjacobson.net is mostly just a front for my Pinboard public links. maybe I’ll merge that idea into this one and put the whole thing at that address. I glanced over the Pinboard gem and I could probably whip something up myself instead of using the linkroll widget. That would give me some more flexibility to display multimedia stuff, Layabout-style and do some more color-coding without having to use jquery like I’m currently doing to emphasize posts with the max_jacobson tag.

I’m just daydreaming here.

some new features here

Originally posted December 13, 2012

Things I’ve added to beefsteak tonight:

more feeds

Like, for individual categories, tags, and search queries. Try clicking on a tag/cat or searching something, and you’ll see a link to the feed at the bottom.

A fun one might be: http://devblog.maxjacobson.net/tag/gush/feed or http://devblog.maxjacobson.net/search/confess/feed if you like me at my gushiest or most confessional.

pages

My about page is now at http://devblog.maxjacobson.net/~about. I made another one mostly to test what it looked like with two. It doesn’t look great.

You can view the markdown source of pages the same as posts. Just add the .md suffix or click the link at the bottom. I don’t know why I offer this. It doesn’t work amazingly. In some posts with code, I see underscores disappear. It’s weird.

favicon and apple touch icon

I just threw in some all-black-errything squares for now. I figure if anyone else uses this they can replace with something they like.


Here’s what the tree for this site looks like right now:

(notice the new pages directory, mostly)

[~/Dropbox/Sites/devblog] [max] [08:23 PM]
 ϡ tree
.
├── config.rb
├── Gemfile
├── Gemfile.lock
├── helpers.rb
├── pages
│   ├── about.md
│   └── projects.md
├── posts
│   ├── 2011-03-12-un-americano.md
│   ├── 2012-02-26-introducing-myself-to-the-command-line.md
│   ├── 2012-08-26-favblogging.md
│   ├── 2012-12-01-added-sorting.md
│   ├── 2012-12-01-already-updates.md
│   ├── 2012-12-01-categories-and-tags.md
│   ├── 2012-12-01-gem-anxiety.md
│   ├── 2012-12-01-sleep.md
│   ├── 2012-12-01-sorting.md
│   ├── 2012-12-01-the-first-post.md
│   ├── 2012-12-02-erb-and-indendation.md
│   ├── 2012-12-02-on-an-airplane.md
│   ├── 2012-12-02-open-source.md
│   ├── 2012-12-02-RSS-is-hard.md
│   ├── 2012-12-02-search.md
│   ├── 2012-12-04-seal-attack.md
│   └── 2012-12-13-meetups.md
├── Procfile
├── public
│   └── img

│       ├── 2012-12-04-seal-1.jpg
│       ├── 2012-12-04-seal-2.jpg
│       ├── 2012-12-04-seal-3.jpg
│       ├── apple-touch-icon.png
│       └── favicon.ico
├── README.md
├── views
│   ├── 404.erb
│   ├── 500.erb
│   ├── layout.erb
│   └── style.scss
└── web.rb

5 directories, 35 files

fuzzy search

Originally posted December 14, 2012

I just made the search a little smarter on this blog. I think. I made it so that when you search a multi-word query, it’ll include posts that match any of the words, not just posts that match all of the words. They’re sorted chronologically, not based on relevance.

And you can put a query in quotes if you want it to match all of the words, in that order.

Here’s how I did that (with some stuff paraphrased):

if query =~ /^".+"$/
  query_array = [query.gsub!(/"/,'')]
else
  query_array = query.split(' ')
end
# ... each post |the_text|
query_array.each do |q|
  if the_text =~ Regexp.new(q, true)
    # then include the post
    break
  end
end

So, first I check if the query is in quotes (I’m coming to really love using regular expressions), and if so I remove the quotes and put that whole string thru. If it’s not in quotes, I split the string into an array of strings, using a space as the delimeter. Then I go through each post and check it against each item in the array. If the query was in quotes, the array only has one item in it. Once there’s a match, I push it thru. The break makes it so once a post matches the query, we move on to the next post rather than keep checking other words in the query against it.

I wonder if I should allow single quotes too. Note to self, allow single quotes.

I wonder what new bugs I just introduced.

heave ho

Originally posted December 22, 2012

So I am happy enough with beefsteak that I am moving this to my proper homepage, http://www.maxjacobson.net.

That space was mainly occupied by my pinboard public links, and I’ve integrated those into beefsteak now.

I considered integrating a pinboard gem but for now I’m sticking with the same old linkroll widget I’ve been using. It’s not super flexible but it has an important feature the main pinboard gem lacks: a distinction between private and public links. It’s not that I have such private stuff in there, it’s just that I have so much stuff in there. As previously described I use IFTTT to send all kinds of stuff automatically, and then I occasionally make a small minority of those links public. And maybe there’s some private stuff in there.

Who is sleepier than I? No one is.

The project is still mostly useable by other people, I think. The only thing is the small jquery script that modifies the DOM so that links with the tag max_jacobson are made red. I tweaked it so it lets you specify what that tag will be, but it’s not working. I’m going to fix that later, maybe.

I create links just to kill them at this point. Old feeds and links have a short shelf life.

beefsteak v2

Originally posted March 19, 2013

This version of beefsteak is brought to you by Justin Timberlake.

I put his new album on repeat eleven or twelve hours ago and starting working.

I realized people might be looking at my GitHub and realized I was embarrassed of the way this blog worked. In the few months from the last update, I learned a lot. I hope I’ll be embarrassed of this in a few months.

Heck I already kind of am.1

The first several posts I wrote for this blog were, naturally, about this blog and the process of building it and excitement of discovery. A lot of it is really dumb but I’m leaving it.

So here’s what’s new:

  • syntax highlighting for code blocks, using my fav colorscheme, cobalt
  • switched from erb to haml – now writing far less HTML by hand
  • appending .md to posts or pages takes you to a text file instead of embedding within a page, which displayed poorly (missing underscores for some reason)
  • some (goofy?) animations on page loads. It picks randomly from a list
  • oh, and when you click to see a footnote, the right one will wiggle. see? 2
  • much better config file; in case anyone besides me uses this system, it should be relatively easy for them to plug in their info and start blogging
  1. or will be in the morning, anyway 

  2. and now I’ve just made it so the return button makes the source from within the blog wiggle, too. I want to learn to write my own CSS3 animations. Right now I’m leaning heavily on Dan Eden. 

click to ugh

January 21, 2013

It’s time for You’re Doing it Wrong, my sometimes series where I complain about blogs whose HTML or CSS bugs me!

Today’s offending blog is The AV Club, which I generally really like and read all the time. Here’s an example post: Jonathan Coulton says Glee ripped off his cover of “Baby God Back”.

How the heck did they come up with this embed code for a YouTube video:

<embed width="425" height="344" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://www.youtube.com/v/Yww4BLjReEk%26hl=en%26fs=1%26rel=0">

Had they copied the embed code from beneath the YouTube video, they would have gotten this:

<iframe width="560" height="315" src="http://www.youtube.com/embed/Yww4BLjReEk" frameborder="0" allowfullscreen></iframe>

I don’t know where The AV Club got their embed code, but exhibit A for it’s outdatedness is the macromedia reference. Try going to that page. Because Macromedia doesn’t exist anymore, you’ll be redirected to Flash’s new owner, Adobe. This post is from three days ago; Adobe acquired Macromedia seven years ago.

Also: every video they embed is given the dimensions 425x344, without regard to the video’s aspect ratio. YouTube’s provided embed code is dimensions-aware and doesn’t introduce unnecessary letterboxing.

So why do I care? The videos still play and it’s pretty much fine I guess. But it screws up ClickToPlugin.

ClickToPlugin is an awesome Safari Extension that blocks plugins like Flash from running until you click on them. It also, when it can, replaces embedded media with a vanilla HTML5 video player. When I typically encounter a YouTube or Vimeo video embedded on a blog, I don’t see their custom Flash player, I see this:

beyonce video

This example is from an AbsolutePunk.net post, Beyoncé Performs Star Spangled Banner [Video]. It behaves much like a regular, Flash YouTube embed – it doesn’t play until you click the triangle although you have preferences like autoplay or auto-preload – it uses Safari’s implementation of the HTML5 video player. Among the benefits: YouTube hasn’t yet figured out how to include ads in the HTML5 videos, it feels faster, and on youtube.com, videos don’t autoplay so I can open six tabs of Taylor Swift videos without causing a terrible cacophany.

But when I visit that AV Club article, I see this:

avclub doesn't have a still frame

Which is fine, I guess. It’s what I signed up for, using this extension. But c’mon, don’t overthink things and get all fancy, stuff’ll get broken.

(AbsolutePunk is doing something custom too. Its code looks like this:

<div align="center"><object width="472" height="389" bgcolor="#f7f7f7"><param name="movie" value="http://www.youtube.com/v/Z-DSFrGnQrk&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="wmode" value="transparent"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Z-DSFrGnQrk&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="472" height="389" bgcolor="#f7f7f7" wmode="transparent"></embed></object></div>

I don’t really understand that either, but I don’t need to, because it behaves the way I expect it to. It looks like all AbsolutePunk video embeds use the same aspect ratio (472x389) but at least it works with ClickToPlugin.)

On Layabout, my web app which is embedding videos all day every day, I see this:

here there is a still frame

Look at that aspect ratio – no black bars! And this is all without manually copying and pasting the embed code from YouTube (or Vimeo in that case). These sites support oEmbed, a protocol for taking a URL and supplying an embed code that works.

Unfortunatley it’s not as well-documented as it could be. Vimeo’s oEmbed API is better in that regard and supports the most important feature: maxwidth. I suspect this is at the root of the hardcoded aspect ratios; designers don’t want videos bursting out of their layouts. Vimeo’s page is very useful and clear. YouTube, as far as I can tell, has only provided one brief blog post on the subject.

Maybe that’s the problem?

using mobile web inspector

January 15, 2013

I’ve just figured out why infinite scrolling wasn’t working on Layabout on my iPod Touch.

I’m using jQuery to detect when the user has reached the bottom of the page. There’s no hardcoded event for that, so you have to do some math using the methods that are given. It goes something like this:

If the user is scrolling, check if the current window height plus the amount of stuff above it is greater than or equal to the total height of the document. This works on the desktop (in the browsers I tested anyway) and on the iPad, but not on my iPod Touch.

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()) {
    // ...
  }
});

On the web, a nice and easy way to figure out problems like these is to use the console and log some variables. So I found myself adding in some stuff like this:

var scroll_top = $(window).scrollTop();
var window_height = $(window).height();
var document_height = $(document).height();
var current_position = scroll_top + window_height;
console.log("scroll top: " + scroll_top);
console.log("window height: " + window_height);
console.log("current position: " + current_position);
console.log("document height: " + document_height);

But it’s not very easy to access the console on an iOS device, so these messages were getting logged to nowhere.

Long story short I followed these instructions and managed to get access to the info I needed. Here’s what the page logged at the bottom of a page:

scroll top: 41628
window height: 1360
current position: 42988
document height: 43173

Huh! No wonder further pages weren’t loading, we were never (by this logic) truly reaching the end of the page!

So, to fix it, I just changed the logic to add 200 pixels of wiggle room, so now it triggers when you get near the bottom of the page rather than hitting it exactly.

So it works and I’m happy. But before we wrap things up too tightly, let’s try to figure out what’s going on here.

Let’s look at some numbers:

thing pixels amount
5th gen iPod Touch screen height 1136
Window height as logged by Mobile Safari ($(window).height()) 1360
The difference between those two 224

What’s the deal with that? Maybe it’s a points-and-pixels thing beyond my comprehension, but this feels kinda wrong to me. Is it possibly a bug in Mobile Safari? Why else would the window height be bigger than the total height of the screen? I expected the opposite; the window height should be less than the screen height, considering that the window doesn’t include browser chrome like the navigation bar along the bottom and sometimes (at the top of pages) the title and address bar.

Let’s revisit the numbers from the earlier log example:

(Note: other than window height, these values would be different on a longer or shorter page)

thing value
scroll top 41628
window height 1360
current position 42988
document height 43173
difference between those last two 185

So if I’m right that Mobile Safari is mis-reporting its height by 224 pixels, how come my earlier logic was falling short by 185 pixels? I think that difference (39 pixels) must be the height of the navigation toolbar?

Maybe!

writing prose with marked

January 12, 2013

Yesterday I got the urge to write some fiction. This has been a decreasingly frequent urge for me, so I seized on it.

I did write a little but I ended up spending more time creating a Marked theme to help me write. Ain’t that how it goes. I set up a GitHub repo to share the theme and any others I may make down the line.

The goal is for me to be able to write in my programmy, vimmy text editor on one half of the screen and for the other half to look as much like a book as I could manage. Also, it prints out nicely (not that I print things, except to PDF). Some of the design features:

  • smart paragraph indenting – follows the physical book’s convention of not unnecessarily indenting the first paragraph in a group of paragraphs
  • kind of musty old book yellow color (but not in printouts)
  • uses google web fonts for a little extra personality
  • classy horizontal rule

A screenshot and the code over on GitHub.