npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

love-notes

v0.1.1

Published

A literate programming tangler and weaver

Downloads

1

Readme

love-notes

A literate programming tool (LPT) for javascript embedded into markdown in the style of CWEB and noweb

What?

Literate Programming is a method of writing code (conceived by Donald Knuth) in which the documentation and code live side-by-side in the source document in such a way that the code can be extracted in a compilable format.

Why?

One of the biggest issues we, as a community of developers, face, is the fact that our documentation doesn't generally reflect the state of mind or decision making process that we, as indivduals, went through when attempting to solve a problem. Worse than that, when we go back to document, or modify the code, we rarely remember why we made the decisions in the first place. Providing a few readable sentences providing an insight as to why a specific design choice was made (or as I've found to be much more insightful in communicating with other developers, why other decisions were not made) is incredibly helpful when attempting to re-enter the mindset you (or others) were in when developing said solution.

Further more, prose, as opposed to, say, a block comment, provides a much more expressive canvas to relate the context of the solution. Block comments intrinsically ask us to be as succinct with information as possible thus causing us to be terse with our documentaiton. Using a prose style of writing is open-ended and allows for as much or as little explanation as needed to properly convey the necessary information.

This method also supplies a more readable medium for the consumer (whether that's yourself in a year's time, or another developer digging through your api). As love-notes uses markdown, the final woven documentation is simple plain html, which allows for an endless amount of possibilities when it comes to stylistic presentation of the information.

Finally, and personally, to me, code is art. When working on personal projects, I find that I often have a story to tell with my code, and a lot of what I put into my work gets lost in translation. Using a literate style of programming, I've found that I enjoy relating (to no-one in particular) the life-events, or the work of friend and peers, that inspired me. It's also helped me learn and retain more information as each project I work on tends to bring with it hours and days of research. As I learn, I write. As I write, I start forming the basic ideas that will, in turn, end up being the project's core.

How?

There are two core abilities that an LPT must be able to perform: Tangling and Weaving.

Tangling is the ability of an LPT to produce "compilable" (or in the case of love-notes bundle-able or interpretable) code. This is achieved through the use of a layer of macros and meta-lingual programming. Currently, love-notes does not support user-defined macros, but there are some built-in macros that can already be used to produce rather robust source. Markdown already has some self-referential abilities in as much as it is a code file, that can produce an Abstract Syntax Tree (AST) that can be easily walked, modified, and rearranged after the fact using wooorm's unified text processing interface.

Weaving, however, is the opposite side of the literate programming coin. This is the ability of an LPT to produce human-readable instructions about a program's development and maintenance. Aside from the fact that markdown is an easy to learn, non-intrusive writing tool, I chose it to be love-notes's work-horse because it already does this. And with some minor tweaks to the AST upon saving, an html file consisting of documentational prose, live examples, and working program code can be made available to the developer, her collaborators, and external developers who wish to consume, or contribute to, the project.

Tangling

Tangling in love-notes is achieved by using codefences and some (currently very limited) macro commands. Program code is tangled using the concepts of CodeStores, CodeFiles and CodeSections. Each love-note produces a single CodeStore that maintains the collection of CodeFiles, and generates the final sources. A CodeFile is created using only a filename, and contains a collection of CodeSection objects, which, in turn, contains a collection of nodes with each holding the raw source for a given code fence. A CodeFile name will, consequently, be the name of the file that is eventually written to disk, and will contain the tangled source for all CodeSections in said file.

Creating your first CodeFile

Technically, you don't have to do anything other than create a single well-formed code fence to create the default CodeFile:

The preceeding example will automatically create a CodeFile named index.js that contains a single CodeSection named root. This CodeSection will then contain a single source block that holds the MDAST node for this codefence. Any code fence you create that doesn't have a macro attached to it will automatically append the code to the root section of the index.js file. Here's another example:

This example, however, will create a CodeFile named math.js containing 3 CodeSections: root, #sum, and #other-methods. Out of the three sections created, only the root section will currently contain any source blocks. The source for math.js#root currently holds an MDAST node that contains a content property with a value of //composable math functions\n#sum\#product\n. However, the root section also now knows that it has two child sections, specifically: [ '#sum', '#root']. The CodeFile representing math.js, will use this information to build a dependency tree while generating the final source for the file. Again, just like in index.js, any further code fences wishing to insert into math.js that don't provide a section, will insert code blocks into the root section of math.js. #CodeSections are created if, and only if, a #section-tag starts a line, and is the only text a line contains

But, let me demonstrate how to target sections:

Each of these blocks target specifc sections of a file. The first being math.js#sum, the second being math.js#root and the final being math.js#other-methods. If source were generated at this moment from this file, it would look like:

// composable math functions
function sum(a,b) {
  return a + b
}
// section: #other-methods
// section: #exports

Just for sake of completion, I'm going to quickly fill out the rest of this little project.

When run through the love-notes tangler and weaver tools, this document will produce two code files (index.js and math.js) and an html file containing both the documentation and code blocks. see output here

Inline Tangling

TODO: More robust documentation Use the <3 macro to insert the contents of a codeblock directly into the woven html file