diff --git "a/Icon\r" "b/Project 01/Icon\r" similarity index 100% rename from "Icon\r" rename to "Project 01/Icon\r" diff --git a/Lab/testing1.md b/Project 01/Lab/testing1.md similarity index 100% rename from Lab/testing1.md rename to Project 01/Lab/testing1.md diff --git a/Makefile b/Project 01/Makefile similarity index 100% rename from Makefile rename to Project 01/Makefile diff --git a/README.markdown b/Project 01/README.markdown similarity index 100% rename from README.markdown rename to Project 01/README.markdown diff --git a/aa-overview.md b/Project 01/aa-overview.md similarity index 100% rename from aa-overview.md rename to Project 01/aa-overview.md diff --git a/buildNotesList.py b/Project 01/buildNotesList.py similarity index 100% rename from buildNotesList.py rename to Project 01/buildNotesList.py diff --git a/buildPage.py b/Project 01/buildPage.py similarity index 100% rename from buildPage.py rename to Project 01/buildPage.py diff --git a/footer.tmpl b/Project 01/footer.tmpl similarity index 100% rename from footer.tmpl rename to Project 01/footer.tmpl diff --git a/header.tmpl b/Project 01/header.tmpl similarity index 100% rename from header.tmpl rename to Project 01/header.tmpl diff --git a/notes-print.css b/Project 01/notes-print.css similarity index 100% rename from notes-print.css rename to Project 01/notes-print.css diff --git a/notes.css b/Project 01/notes.css similarity index 100% rename from notes.css rename to Project 01/notes.css diff --git a/project.info b/Project 01/project.info similarity index 100% rename from project.info rename to Project 01/project.info diff --git a/styleLineNumbers.js b/Project 01/styleLineNumbers.js similarity index 100% rename from styleLineNumbers.js rename to Project 01/styleLineNumbers.js diff --git "a/_master/Icon\r" "b/_master/Icon\r" new file mode 100755 index 0000000..e69de29 diff --git a/_master/Lab/testing1.md b/_master/Lab/testing1.md new file mode 100644 index 0000000..60f4055 --- /dev/null +++ b/_master/Lab/testing1.md @@ -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. diff --git a/_master/Makefile b/_master/Makefile new file mode 100755 index 0000000..84ae347 --- /dev/null +++ b/_master/Makefile @@ -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 diff --git a/_master/README.markdown b/_master/README.markdown new file mode 100644 index 0000000..5d93191 --- /dev/null +++ b/_master/README.markdown @@ -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. + + + +# 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. + + + +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/ diff --git a/_master/aa-overview.md b/_master/aa-overview.md new file mode 100755 index 0000000..8d3f213 --- /dev/null +++ b/_master/aa-overview.md @@ -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. \ No newline at end of file diff --git a/_master/buildNotesList.py b/_master/buildNotesList.py new file mode 100644 index 0000000..c361e19 --- /dev/null +++ b/_master/buildNotesList.py @@ -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) + "…" + f.close() + fileLI.append('
  • %s
  • ' % (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 += ['
  • %s' % d[2:], '', '
  • '] + +print '''function showNotesList(root){ + document.write('%s') +}''' % ''.join(linkList) diff --git a/_master/buildPage.py b/_master/buildPage.py new file mode 100755 index 0000000..1273eac --- /dev/null +++ b/_master/buildPage.py @@ -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('
  • %s
  • ' % c[0]) + else: + contactLI.append('
  • %s
  • '\ + % 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) diff --git a/_master/footer.tmpl b/_master/footer.tmpl new file mode 100755 index 0000000..10bace8 --- /dev/null +++ b/_master/footer.tmpl @@ -0,0 +1,13 @@ +
    +

    + Source: +
    + Last modified: $modldate at $modtime
    + +

    + + + + diff --git a/_master/header.tmpl b/_master/header.tmpl new file mode 100755 index 0000000..c0f2b58 --- /dev/null +++ b/_master/header.tmpl @@ -0,0 +1,48 @@ + + + + $projname ($projnumber) + + + + + + + + +
    +
    +

    $projname

    +

    $projnumber

    +
    + + +
    \ No newline at end of file diff --git a/_master/notes-print.css b/_master/notes-print.css new file mode 100644 index 0000000..47847f3 --- /dev/null +++ b/_master/notes-print.css @@ -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; +}*/ \ No newline at end of file diff --git a/_master/notes.css b/_master/notes.css new file mode 100755 index 0000000..d6b604b --- /dev/null +++ b/_master/notes.css @@ -0,0 +1,161 @@ +body { + background-color: #4977CD; +} + +h1, h2, h3, h4, h5 { + font-family: Helvetica, Sans-Serif; +} + +a { + color: #002165; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +#container { + width: 50em; + background-color: #CADDFF; + margin-left: auto; + margin-right: auto; +} + +#title { + background-color: #039; + color: white; + padding-left: 1em; + padding-right: 1em; + padding-bottom: 1em; + padding-top: 1em; +} + +#title h1 { + margin: 0; + padding: 0; +} + +#title .left { + margin: 0; + padding: 0; + float: left; + text-align: left; +} + +#title .right { + margin: 0; + padding: 0; + text-align: right; +} + + +#sidebar { + background-color: #CADDFF; + font-size: 85%; + font-family: Helvetica, Sans-serif; + width: 10em; + padding: 1em .5em 1em .5em; + margin: 0 0 0 0; + float: right; +} + +#sidebar ul { + margin-left: 0em; + padding-left: .75em; + list-style-position: outside; + list-style-type: none; +} + +#sidebar ul li { + margin-bottom: .5em; +} + +#sidebar h1 { + font-size: 100%; +} + +#sidebar a { + color: black; +} + +#sidebar hr { + background-color: #002165; + border: 0; + height: 2px; + width: 75%; +} + +#note { + background-color: white; + margin-top 0em; + margin-right: 9.35em; /* (10 + .5 + .5)*.85 */ + padding: 1em 1em 1em 2em; + /* float: left;*/ +} + +#note h1 { + font-size: 150%; +} + +#note h2 { + font-size: 125%; +} + +#note h3 { + font-size: 100%; +} + +#note h4,h5 { + font-size: 80%; +} + +#note img.c { + display: block; + margin-left: auto; + margin-right: auto; +} + +#note pre span.ln { + color: #888; + font-size: 75%; +} + +#note .info { + font-size: 75%; + color: #888; +} + +#note .info a { + color: #4977CD; +} + +#note table { + border-collapse: collapse; +} + +#note table th { + padding: .5em 1em .25em 1em; + background-color: #ddd; + border: 1px solid black; + border-bottom: 2px solid black; +} + +#note table td { + padding: .25em 1em .25em 1em; + border: 1px solid black; +} + +#note ol,ul { + margin-top: .5em; + margin-bottom: .5em; +} + +#note li { + margin-top: .5em; +} + +#note p.self { + background-color: #faa; +} + diff --git a/_master/project.info b/_master/project.info new file mode 100755 index 0000000..69049da --- /dev/null +++ b/_master/project.info @@ -0,0 +1,5 @@ +jsmathpath = file:///Users/mark/Library/JavaScript/jsMath/easy/load.js +dirname = notes +projname = Project Name +projnumber = 9999 +contact = Apple:A1A2AA41-FA30-40AE-9925-FD6DB270B0A5%3AABPerson diff --git a/_master/styleLineNumbers.js b/_master/styleLineNumbers.js new file mode 100755 index 0000000..724a595 --- /dev/null +++ b/_master/styleLineNumbers.js @@ -0,0 +1,30 @@ +function styleLN() { + var preElems = document.getElementsByTagName('pre'); + if (0 == preElems.length) { // no pre elements; stop + return; + } + for (var i = 0; i < preElems.length; i++) { + var pre = preElems[i]; + var code = pre.getElementsByTagName('code')[0]; + if (null == code) { // no code; move on + continue; + } + var oldContent = code.innerHTML; + var newContent = oldContent.replace(/^( *)(\d+):( )/mg, + '$1$2$3<' + '/span>'); + if (oldContent.match(/^( *)(\d+):( )/mg)) { + newContent += "\n" + ''; + } + code.innerHTML = newContent; + } +} + +function toggleLN(code) { + for (var i=0; i