Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file added _master/Icon
Empty file.
9 changes: 9 additions & 0 deletions _master/Lab/testing1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# January 1, 2010 tests #

Just a simple list:

* Did this
* Did that
* Did something else

And there'd probably be some conclusions.
15 changes: 15 additions & 0 deletions _master/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Makefile for project notes.

mdfiles := $(wildcard *.md */*.md)
htmlfiles := $(patsubst %.md, %.html, $(mdfiles))

all: notesList.js $(htmlfiles)

notesList.js::
python buildNotesList.py > notesList.js

%.html: %.md project.info header.tmpl footer.tmpl
python buildPage.py $* > $@

clean:
rm $(htmlfiles) notesList.js
83 changes: 83 additions & 0 deletions _master/README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
This is a no-server personal wiki system that I created to keep track of project notes for work. I've put it here because it may be useful to others.

<img class="ss" src="http://www.leancrew.com/all-this/images/notes-wiki-overview.png" />

# Goals #

This is what I want:

1. A self-contained file or folder of files that includes everything needed to write and view the notes. I want it to be easy to copy from one computer to another and to archive to DVD. This eliminates most of the available wiki systems, which store everything in a central database.
2. The notes themselves to be written in Markdown rather than some specialized wiki markup. I write everything in Markdown and don’t want to shift context when switching from notes to a report. In fact, I'd like to be able to copy directly from my notes—markup included—when writing a report.
3. To write the notes in my text editor of choice rather than in an HTML text input box or a word processor. Currently, that editor is TextMate, but TextMate itself isn’t the point. The point is to take advantage of the comfort I feel working in my normal editor. There's a reason old Unix hackers like to do everything in Emacs or vi; it's just more efficient to do all your text work in one environment.
4. To be able to change the visual style of the notes as my needs or tastes change.
5. To create new notes quickly and easily.

# Requirements #

Apart from what's in the repository, you'll need

* [Python][1]. The two build scripts, `buildPage.py` and `buildNotesList.py`, are written in Python.
* [GNU make][2]. The build scripts are controlled by a makefile.
* A [Markdown][3] processor. I use a self-customized version of Fletcher Penney's [MultiMarkdown][4]. Whatever you use, you'll have to provide the name of that command on Line 16 of `buildPage.py`.
* A [SmartyPants][5] processor. I use Gruber's SmartyPants. Again, you'll have to provide the name of that command on Line 16 of `buildPage.py`.

If you need to include mathematical formulas in your notes, you should consider installing Davide Cervone's [jsMath][6]. Once you've installed it, you can activate jsMath in the notes by uncommenting Line 10 of the `header.tmpl` file and adjusting the `jsmathpath` variable in the `project.info` file to point to jsMath's `easy.js` file.

# File structure #

The top level of the notes directory contains all the support files, that is, all the files that are distinct from the notes themselves. These files are:

* `header.tmpl`, the HTML template file with all the common code above the content.
* `footer.tmpl`, the HTML template file with all the common code below the content.
* `project.info`, a file of project-specific data, including the project name and number, the list of contacts (including links to Address Book entries if you're on a Mac), and the name of the PNotes directory.
* `notes.css`, the style file for browsing.
* `notes-print.css`, the style file for printing.
* `styleLineNumbers.js`, a [pair of JavaScript functions][7] that improve the formatting of source code.
* `buildPage.py`, a Python script that combines a Markdown input file with the template files and produces a single HTML file.
* `buildNotesList.py`, a Python script that searches the directory (and subdirectories) for notes files and generates a list of links to all the notes for display in the sidebar.
* `Makefile`, the makefile that controls the build scripts.

Notes files contain the actual content. These files should all have the extension `.md` and can be in both the top-level directory and in subdirectories. Two sample notes files are included: `aa-overview.md` in the top-level directory, and `testing1.md` in the `Lab` subdirectory.

# Creating notes #

As mentioned above, notes are just plain text files written in Markdown and saved with an `.md` extension. The first line will be the note's title and will appear in the sidebar.

<img class="ss" src="http://www.leancrew.com/all-this/images2010/notes-sidebar.png" />

I use ATX-style headers, with hash marks indicating the header level, and I start each file with a first-level header, like this:

# Overview #

The build system is smart enough to get rid of the hash marks when making up the sidebar.

Notes files in subdirectories appear with greater indentation under the name of the directory—like an outline. Within each directory, the notes are ordered alphabetically according to their file names, so you can rearrange the order in which the notes appear in the sidebar by changing the file names without changing their content. At present, there's no way to change the order of the subdirectories.

Executing `make` from the top-level directory will generate all the HTML pages, which can be opened with any browser. Subsequent executions of `make` will generate only those pages whose `.md` files are new or have been modified. Executing `make clean` will erase all the HTML files, but will not touch the `.md` files.

# Editing notes #

You can, of course, open any `.md` file in any text editor to make changes. If you're using TextMate on a Mac, there's a faster way: click the Edit in TextMate link in the side bar to instantly open the `.md` file in TextMate—no need to switch to the Finder, open the folder, and double-click the file icon. If you're a BBEdit user, you can do the same thing, but you'll probably want to change the name of the link. It's on Line 33 of `header.tmpl`.

# More details #

I wrote a three-part series of blog posts describing this system and its scripts, [here][8], [here][9], and [here][10]. Updates to the system are described [here][12] and [here][13].

# License #

This work is licensed under a [Creative Commons Attribution-Share Alike 3.0 Unported License][11]. Do what you want with it, but provide a link back to either my blog posts or to my repository.


[1]: http://www.python.org/
[2]: http://www.gnu.org/software/make/
[3]: http://daringfireball.net/projects/markdown/
[4]: http://fletcherpenney.net/multimarkdown/
[5]: http://daringfireball.net/projects/smartypants/
[6]: http://www.math.union.edu/~dpvc/jsMath/
[7]: http://www.leancrew.com/all-this/2007/12/source-code-line-numbers-and-javascript/
[8]: http://www.leancrew.com/all-this/2008/06/my-no-server-personal-wiki-part-1/
[9]: http://www.leancrew.com/all-this/2008/06/my-no-server-personal-wiki—part-2/
[10]: http://www.leancrew.com/all-this/2008/06/my-no-server-personal-wiki—part-3/
[11]: http://creativecommons.org/licenses/by-sa/3.0/
[12]: http://www.leancrew.com/all-this/2010/02/the-no-server-notes-wiki/
[13]: http://www.leancrew.com/all-this/2010/05/relative-links-in-pnotes/
7 changes: 7 additions & 0 deletions _master/aa-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Overview #

## Background ##

This is where I describe the project.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
57 changes: 57 additions & 0 deletions _master/buildNotesList.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/python

import os

# Get the titles of all the notes files in the directory. The
# title is assumed to be the first line of the file. Truncate
# the title at a word boundary if it's longer than maxlength,
# and turn it into a link in a list item.
def nameList(dir):
fileLI = []
maxlength = 35
allFiles = os.listdir(dir)
baseNames = [ f[:-3] for f in allFiles if f[-3:] == '.md' ]
# print baseNames
for fn in baseNames:
f = file(os.path.join(d, fn + '.md'))
top = f.readline()
title = top.strip('# \n')
if len(title) > maxlength:
words = title.split()
twords = []
count = 0
for w in words:
if count + len(w) > maxlength:
break
else:
twords.append(w)
count += len(w) + 1
title = ' '.join(twords) + "&#8230;"
f.close()
fileLI.append('<li><a href="\' + root + \'%s.html">%s</a></li>' % (os.path.join(d, fn),title))
return fileLI

# Find all the directories that have md files.
mdDirs = []
for root, dirs, files in os.walk('.'):
for f in files:
if f[-3:] == '.md':
mdDirs.append(root)
break

# Go through the directories and generate the list of links.
linkList = []
for d in mdDirs:
if d == '.':
linkList += nameList(d)
# print linkList
else:
linkList += ['<li>%s' % d[2:], '<ul>']
# print linkList
linkList += nameList(d)
# print linkList
linkList += ['</ul>', '</li>']

print '''function showNotesList(root){
document.write('%s')
}''' % ''.join(linkList)
87 changes: 87 additions & 0 deletions _master/buildPage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python

import sys
import os
import os.path
import time
import string
import urllib

# The argument is the basename of the Markdown source file.
mdFile = sys.argv[1] + '.md'

# Open the page files and process the content.
header = open('header.tmpl', 'r')
footer = open('footer.tmpl', 'r')
cmd = 'MultiMarkdown %s | SmartyPants' % mdFile
content = os.popen(cmd, 'r')

# Make the template.
templateParts = [header.read(), content.read(), footer.read()]
template = string.Template(''.join(templateParts))

# Close the page files.
header.close()
footer.close()
content.close()

# Initialize the dictionary of dynamic information.
info = {}

# Dictionary entry with relative path to notes root. We allow only one
# level of subdirectory, so the root can be at most one level up from
# the file we're working on.
if os.path.split(mdFile)[0] == '':
info['root'] = ''
else:
info['root'] = '../'

# Dictionary entry with long modification date of the Markdown file.
mdModTime = time.localtime(os.path.getmtime(mdFile))
info['modldate'] = time.strftime('%B %e, %Y', mdModTime)
info['modldate'] = info['modldate'].replace(' ', ' ')

# Dictionary entry with short modification date of the Markdown file.
info['modsdate'] = time.strftime('%m/%e/%y', mdModTime)
info['modsdate'] = info['modsdate'].replace(' ', '')

# Dictionary entry with modification time of the Markdown file.
info['modtime'] = time.strftime('%l:%M %p', mdModTime)
if info['modtime'][0] == ' ':
info['modtime'] = info['modtime'][1:]

# Dictionary entry with absolute path to the Markdown file (for editing).
# info['mdpath'] = os.path.abspath(mdFile)

# Add project info to the dictionary.
projInfo = open('project.info', 'r')
for line in projInfo:
if line[0] == '#' or line.strip() == '':
continue
name, value = [s.strip() for s in line.split('=', 1)]
if name in info:
info[name] += '\n' + value
else:
info[name] = value

projInfo.close()

# Dictionary entry with path to project info file (for editing).
# info['infopath'] = os.path.abspath('project.info')

# Convert the contacts into a series of HTML list items.
if 'contact' in info:
contactLI = []
cl = [s.split(':',1) for s in info['contact'].split('\n')]
for c in cl:
if len(c) == 1:
contactLI.append('<li>%s</li>' % c[0])
else:
contactLI.append('<li><a href="addressbook://%s">%s</a></li>'\
% tuple(reversed(c)))
info['contactlist'] = '\n'.join(contactLI)
else:
info['contactlist'] = ''

# Output the template with the dynamic information substituted in.
print template.safe_substitute(info)
13 changes: 13 additions & 0 deletions _master/footer.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<hr />
<p class="info">
Source:
<script type="text/javascript">
document.write('<a href="txmt://open?url=' + document.URL.replace(/html$/, 'md') + '">' + document.URL.replace(/html$/, 'md') + '</a></li>\n')
</script><br />
Last modified: $modldate at $modtime<br />
<!-- This page built: $buildtime -->
</p>
</div> <!-- note -->
</div> <!-- container -->
</body>
</html>
48 changes: 48 additions & 0 deletions _master/header.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>$projname ($projnumber)</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="all" href="${root}notes.css" />
<link rel="stylesheet" type="text/css" media="print" href="${root}notes-print.css" />
<!-- <script type="text/javascript" src="$jsmathpath"></script> -->
<script type="text/javascript" src="${root}styleLineNumbers.js"></script>
<script type="text/javascript" src="${root}notesList.js"></script>
</head>
<body onload="styleLN()">
<div id="container">
<div id="title">
<h1 class="left">$projname</h1>
<h1 class="right">$projnumber</h1>
</div> <!-- title -->
<div id="sidebar">
<h1>Project notes:</h1>
<ul>
<script type="text/javascript">showNotesList('$root')</script>
</ul>
<hr />
<h1>Contacts:</h1>
<ul>
$contactlist
</ul>
<hr />
<h1>Source:</h1>
<ul>
<li><script type="text/javascript">
document.write('<a href="txmt://open?url=' + document.URL.replace(/html$/, 'md') + '">Edit in TextMate</a></li>\n')
</script>
<li>Last modified<br />
&nbsp;$modldate<br />
&nbsp;at $modtime</li>
</ul>
<hr />
<ul>
<li><script type="text/javascript">
infoPath = document.URL.replace(/\/$dirname\/.+$/, '/$dirname/project.info');
document.write('<a href="txmt://open?url=' + infoPath + '">Edit project info</a>');
</script></li>
</ul>
</div> <!-- sidebar -->

<div id="note">
36 changes: 36 additions & 0 deletions _master/notes-print.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
body {
background-color: white;
}

#container {
background: white;
}

#container a {
color: black;
}

#title {
background-color: white;
color: black;
}

#sidebar {
display: none;
}

#note {
margin-right: 0;
}

#note .info {
display: none;
}

#note hr {
display: none;
}

/*#note .info a {
color: #888;
}*/
Loading