Document mathematical Go code beautifully

Related tags

mathfmt
Overview

mathfmt

Document mathematical Go code beautifully.

  • Write mathematical formulae in a LaTeX-ish syntax
  • Super/subscripts formatted with Unicode characters: 2^32 becomes 2³² and x_{i+1} becomes xᵢ₊₁
  • Comprehensive symbol library: \zeta(s) = \sum 1/n^{s} becomes ζ(s) = ∑ 1/nˢ

Inspired by Filippo Valsorda's literate Go implementation of Poly1305, which can be reproduced using mathfmt.

Usage

Install mathfmt with:

go get -u github.com/mmcloughlin/mathfmt

Apply to files just like you would with gofmt.

mathfmt -w file.go

Example

Here's our variance function in Go, documented with LaTeX-ish equations in comments.

// Variance computes the population variance of the population x_{i} of size N.
// Specifically, it computes \sigma^2 where
//
//		\sigma^2 = \sum (x_{i} - \mu)^2 / N
//
// See also: https://en.wikipedia.org/wiki/Variance.
func Variance(X []float64) float64 {
	// Compute the average \mu.
	mu := Mean(X)

	// Compute the sum \sum (x_{i} - \mu)^2.
	ss := 0.0
	for _, x := range X {
		ss += (x - mu) * (x - mu) // (x_{i} - \mu)^2
	}

	// Final divide by N to produce \sigma^2.
	return ss / float64(len(X))
}

Run it through mathfmt and voila!

// Variance computes the population variance of the population xᵢ of size N.
// Specifically, it computes σ² where
//
//		σ² = ∑ (xᵢ - μ)² / N
//
// See also: https://en.wikipedia.org/wiki/Variance.
func Variance(X []float64) float64 {
	// Compute the average μ.
	mu := Mean(X)

	// Compute the sum ∑ (xᵢ - μ)².
	ss := 0.0
	for _, x := range X {
		ss += (x - mu) * (x - mu) // (xᵢ - μ)²
	}

	// Final divide by N to produce σ².
	return ss / float64(len(X))
}

Syntax

First a warning: mathfmt does not have a rigorous grammar, it's a combination of string replacement and regular expressions that appears to work most of time. However you may run into some thorny edge cases.

Source

mathfmt only works on Go source code. Every comment in the file is processed, both single- and multi-line.

Symbols

mathfmt recognizes a huge symbol table that is almost entirely borrowed from LaTeX packages. Every symbol macro in comment text will be replaced with its corresponding Unicode character. In addition to LaTeX symbol macros, mathfmt supports a limited set of "aliases" for character combinations commonly used to represent mathematical symbols.

Super/subscripts

Like LaTeX, superscripts use the ^ character and subscripts use _. If the super/subscript consists entirely of digits, then no braces are required: for example 2^128 or x_13. Otherwise braces must be used to surround the super/subscript, for example 2^{i} or x_{i+j}.

Note that Unicode support for super/subscripts is limited, and in particular does not support the full alphabet. Therefore, if there is not a corresponding super/subscript character available for any character in braces {...}, mathfmt will not perform any substition at all. For example there is no superscript q, so mathfmt will not be able to process 2^{q}, and likewise with x_{K}.

Credits

Thank you to Günter Milde for the exhaustive unimathsymbols database of Unicode symbols and corresponding LaTeX math mode commands.

License

mathfmt is available under the BSD 3-Clause License.

Issues
  • testing: literate poly1305 test case

    testing: literate poly1305 test case

    Since it sparked the idea in the first place, it would be good to have a test case based on @FiloSottile's literate poly1305 implementation.

    https://blog.filippo.io/a-literate-go-implementation-of-poly1305/

    opened by mmcloughlin 1
  • can you make one that can format any plain text

    can you make one that can format any plain text

    Currently it requires the input to be Go source code. I need one that can work on any text file.

    enhancement 
    opened by ghost 1
  • `\eta_2`

    `\eta_2`

    I would expect it to be formatted as η₂.

    (Let me just reiterate that I absolutely love this tool.)

    opened by bwesterb 1
  • ci: initial setup

    ci: initial setup

    null

    opened by mmcloughlin 0
  • latex symbols

    latex symbols

    Would be good to support a much more extensive set of symbols. Probably matching the LaTeX definitions would make sense. The following page provides a database we could use:

    http://milde.users.sourceforge.net/LUCR/Math/

    opened by mmcloughlin 0
  • rework and test against poly1305

    rework and test against poly1305

    Fixes #2

    opened by mmcloughlin 0
  • use latex symbol macros

    use latex symbol macros

    Fixes #4

    opened by mmcloughlin 0
  • attempt to make \mathfmt{...} unnecessary or optional

    attempt to make \mathfmt{...} unnecessary or optional

    The \mathfmt{...} macro makes this more difficult to use than you'd like. Try to revert to the original implementation without it.

    opened by mmcloughlin 0
  • remove \mathfmt{...} macro

    remove \mathfmt{...} macro

    • Now all comment text is processed as a formula.
    • Uses go ast tooling, therefore limits this tool to Go source code

    Fixes #7

    opened by mmcloughlin 0
  • regexp refactor

    regexp refactor

    Updates #3 #9

    opened by mmcloughlin 0
  • nasty edge cases

    nasty edge cases

    Collection of edge cases that are not handled well. See also #3.

    Chained super/subscripts: For example in x/crypto/pkcs12:

    	//       Z_2^u x Z_2^v -> Z_2^u
    

    https://github.com/golang/crypto/blob/c9f3fb736b729628ec1e9c1a6b4313e883f452f9/pkcs12/pbkdf.go#L38

    Punctuation prior: For example:

    		//        A.  Set A2=H^r(D||I). (i.e., the r-th hash of D||1,
    

    https://github.com/golang/crypto/blob/c9f3fb736b729628ec1e9c1a6b4313e883f452f9/pkcs12/pbkdf.go#L108

    Tables: In the below, the -+ gets replaced with a "MINUS-PLUS" symbol.

    //	                  |  USTAR |       PAX |       GNU
    //	------------------+--------+-----------+----------
    //	Name              |   256B | unlimited | unlimited
    //	Linkname          |   100B | unlimited | unlimited
    

    https://github.com/golang/go/blob/f770366f6d910e4bf92a6f885908afe134d65b23/src/archive/tar/format.go#L19-L22

    Channel syntax: Source code in a comment replaced with a unicode arrow.

    //	x, ok := <-c
    

    https://github.com/golang/go/blob/f770366f6d910e4bf92a6f885908afe134d65b23/src/builtin/buil tin.go#L218

    Quoted strings:

    	// R1 op R2 or r1 op constant.
    	// op is:
    	//	"<<" == 0
    	//	">>" == 1
    	//	"->" == 2
    	//	"@>" == 3
    

    https://github.com/golang/go/blob/f770366f6d910e4bf92a6f885908afe134d65b23/src/cmd/asm/internal/asm/parse.go#L610-L615

    Comment dividers:

    // The original C code, the long comment, and the constants
    // below are from FreeBSD's /usr/src/lib/msun/src/s_log1p.c
    // and came with this notice. The go code is a simplified
    // version of the original C.
    //
    // ====================================================
    // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    //
    // Developed at SunPro, a Sun Microsystems, Inc. business.
    // Permission to use, copy, modify, and distribute this
    // software is freely granted, provided that this notice
    // is preserved.
    // ====================================================
    

    https://github.com/golang/go/blob/f770366f6d910e4bf92a6f885908afe134d65b23/src/math/log1p.go#L7-L19

    Windows filepaths: Can be interpreted as LaTeX symbols:

    //   * UNC paths                              (e.g \\server\share\foo\bar)
    //   * absolute paths                         (e.g C:\foo\bar)
    //   * relative paths begin with drive letter (e.g C:foo\bar, C:..\foo\bar, C:.., C:.)
    //   * relative paths begin with '\'          (e.g \foo\bar)
    //   * relative paths begin without '\'       (e.g foo\bar, ..\foo\bar, .., .)
    

    https://github.com/golang/go/blob/f770366f6d910e4bf92a6f885908afe134d65b23/src/path/filepath/symlink_windows.go#L52-L56

    opened by mmcloughlin 1
  • testing: stdlib examples

    testing: stdlib examples

    The standard library has a lot of examples of this kind of thing. Perhaps use them for test cases?

    Related #2

    opened by mmcloughlin 3
Owner
Michael McLoughlin
Michael McLoughlin
Go library that makes it easy to work with physical types, e.g. distances, velocities and angles.

Units Use at your own risk Note that this library is NOT production ready. If you want to use it anyway, contributions and bug reports are welcome! Br

Sindre Røkenes Myren 19 Feb 26, 2021
Sparse matrix formats for linear algebra supporting scientific and machine learning applications

Sparse matrix formats Implementations of selected sparse matrix formats for linear algebra supporting scientific and machine learning applications. Co

James Bowman 119 Jul 13, 2021
Naive Bayesian Classification for Golang.

Naive Bayesian Classification Perform naive Bayesian classification into an arbitrary number of classes on sets of strings. bayesian also supports ter

Jake Brukhman 710 Jul 16, 2021
Implements a simple floating point arithmetic expression evaluator in Go (golang).

evaler https://github.com/soniah/evaler Package evaler implements a simple floating point arithmetic expression evaluator. Evaler uses Dijkstra's Shun

Sonia Hamilton 44 Apr 1, 2021
Arbitrary-precision fixed-point decimal numbers in go

decimal Arbitrary-precision fixed-point decimal numbers in go. Note: Decimal library can "only" represent numbers with a maximum of 2^31 digits after

Spring Engineering 3.2k Jul 24, 2021
Arbitrary-precision decimals for Go

apd apd is an arbitrary-precision decimal package for Go. apd implements much of the decimal specification from the General Decimal Arithmetic descrip

CockroachDB 358 May 23, 2021
An arbitrary-precision decimal floating-point arithmetic package for Go

decimal Package decimal implements arbitrary-precision decimal floating-point arithmetic for Go. Rationale How computers represent numbers internally

Denis Bernard 22 Jun 5, 2021
A well tested and comprehensive Golang statistics library package with no dependencies.

Stats - Golang Statistics Package A well tested and comprehensive Golang statistics library / package / module with no dependencies. If you have any s

Montana Flynn 2k Jul 14, 2021
A fast SAT solver

Gini SAT Solver The Gini sat solver is a fast, clean SAT solver written in Go. It is to our knowledge the first ever performant pure-Go SAT solver mad

IRI France R&D Open Organisation 121 Jul 20, 2021
Go Humans! (formatters for units to human friendly sizes)

Humane Units Just a few functions for helping humanize times and sizes. go get it as github.com/dustin/go-humanize, import it as "github.com/dustin/go

Dustin Sallings 2.7k Jul 26, 2021
Go language bindings for the COIN-OR Linear Programming library

clp Description The clp package provides a Go interface to the COIN-OR Linear Programming (CLP) library, part of the COIN-OR (COmputational INfrastruc

Los Alamos National Laboratory 23 Jun 3, 2021
Gives criticality score for an open source project

Open Source Project Criticality Score (Beta) This project is maintained by members of the Securing Critical Projects WG. Goals Generate a criticality

Open Source Security Foundation (OpenSSF) 885 Jul 23, 2021
Golang RServe client. Use R from Go

Roger Roger is a Go RServe client, allowing the capabilities of R to be used from Go applications. The communication between Go and R is via TCP. It i

Senseye 246 Jul 4, 2021
Go bindings for fftw3

Go bindings for FFTW v3.2.2 Maintained by Jonathan Wills: [email protected] Feel free to email me patches, suggestions or bugs. FFTW homepage: htt

null 38 Nov 22, 2020