README fine-tuning and build.rs for uglifying it for rustdoc.

Thu, 01 Dec 2022 23:37:14 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 01 Dec 2022 23:37:14 +0200
changeset 6
bcb508479948
parent 5
df971c81282e
child 7
c32171f7cce5

README fine-tuning and build.rs for uglifying it for rustdoc.

Cargo.lock file | annotate | diff | comparison | revisions
Cargo.toml file | annotate | diff | comparison | revisions
README.md file | annotate | diff | comparison | revisions
build.rs file | annotate | diff | comparison | revisions
misc/cargo-d file | annotate | diff | comparison | revisions
misc/doc_alias.sh file | annotate | diff | comparison | revisions
src/main.rs file | annotate | diff | comparison | revisions
--- a/Cargo.lock	Thu Dec 01 23:46:09 2022 +0200
+++ b/Cargo.lock	Thu Dec 01 23:37:14 2022 +0200
@@ -29,6 +29,15 @@
 checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
+name = "aho-corasick"
+version = "0.7.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "alg_tools"
 version = "0.1.0"
 dependencies = [
@@ -926,6 +935,7 @@
  "poloto",
  "rand",
  "rand_distr",
+ "regex",
  "rgb",
  "serde",
  "serde_json",
@@ -1058,12 +1068,29 @@
 ]
 
 [[package]]
+name = "regex"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
 name = "regex-automata"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
 
 [[package]]
+name = "regex-syntax"
+version = "0.6.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
+
+[[package]]
 name = "rgb"
 version = "0.8.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
--- a/Cargo.toml	Thu Dec 01 23:46:09 2022 +0200
+++ b/Cargo.toml	Thu Dec 01 23:37:14 2022 +0200
@@ -41,5 +41,8 @@
 serde_json = "~1.0.85"
 chrono = { version = "~0.4.23", features = ["alloc", "std", "serde"] }
 
+[build-dependencies]
+regex = "~1.7.0"
+
 [profile.release]
 debug = true
--- a/README.md	Thu Dec 01 23:46:09 2022 +0200
+++ b/README.md	Thu Dec 01 23:37:14 2022 +0200
@@ -1,42 +1,95 @@
 
-# pointsource_algs
+# Proximal methods for point source localisation: the implementation
 
-This repository contains [Rust][] codes for the manuscript “_Proximal methods for point source localisation_” by Tuomo Valkonen ⟨tuomov@iki.fi⟩.
-It concerns solution of problems of the type
+This package contains [Rust][] codes for the manuscript “_Proximal methods for
+point source localisation_” by Tuomo Valkonen ⟨tuomov@iki.fi⟩. It concerns
+solution of problems of the type
 $$
     \min_{μ ∈ ℳ(Ω)}~ F(x) + λ \|μ\|_{ℳ(Ω)} + δ_{≥ 0}(x),
 $$
-where $F(x)=\frac12\|Ax-b\|_2^2$ and $A \in 𝕃(ℳ(Ω); ℝ^m)$, and $ℳ(Ω)$ is the space of Radon measures on the (rectangular) domain $Ω ⊂ ℝ^n$.
+where $F$ is a data term, and $ℳ(Ω)$ is the space of Radon measures on the
+(rectangular) domain $Ω ⊂ ℝ^n$. Implemented are $F(x)=\frac12\|Ax-b\|_2^2$ and
+$F(x)=\|Ax-b\|_1$ for the forward operator $A \in 𝕃(ℳ(Ω); ℝ^m)$ modelling a
+simple sensor grid. For the 2-norm-squared data term implemented are the
+algorithms μFB, μFISTA, and μPDPS from the aforementioned manuscript along with
+comparison relaxed and fully corrective conditional gradient methods from the
+literature. For the 1-norm data term only the μPDPS is applicable.
 
 ## Installation and usage
 
-First install the Install [Rust][] compiler and `cargo`.
-Also install the [GNU Scientific Library][gsl]. On a Mac with [Homebrew][]
-installed, the latter can be done with
-```sh
-$ brew install gsl
+### Installing dependencies
+
+Most dependencies are managed by the Cargo build system of [Rust][]. You will
+only need to install the “nightly” Rust compiler and the
+[GNU Scientific Library][gsl] manually. At the time of writing this README,
+[alg_tools][] also needs to be downloaded separately.
+
+1.  Install the [Rust][] infrastructure (including Cargo) with [rustup][].
+2.  Install a “nightly” release of the Rust compiler. With rustup, installed in
+    the previous step, this can be done with
+    ```console
+    rustup toolchain install nightly
+    ```
+3.  Install [GNU Scientific Library][gsl]. On a Mac with [Homebrew] installed,
+    this can be done with
+    ```console
+    brew install gsl
+    ```
+    For other operating systems, suggestions are available in the
+    [rust-GSL crate documentation][rust-GSL].
+    On Windows, you will likely need to pass extra `RUSTFLAGS` options to
+    Cargo in the following steps to locate the library.
+
+4. Download [alg_tools][] and unpack it under the same directory as this
+   package.
+
+  [rustup]: https://rustup.rs
+  [alg_tools]: https://tuomov.iki.fi/software/alg_tools/
+  [Rust]: https://www.rust-lang.org/
+  [rust-GSL]: https://docs.rs/GSL/6.0.0/rgsl/
+  [gsl]: https://www.gnu.org/software/gsl/
+  [Homebrew]: https://brew.sh
+
+### Building and running the experiments
+
+To compile the code and run the experiments in the manuscript, use
+```console
+cargo run --release
 ```
-Then download [alg_tools][] and unpack it under the same directory as this package.
-To compile the code and run the experiments in the manuscript, use
-```sh
-$ cargo run --release
-```
+When doing this for the first time, several dependencies will be downloaded.
 The `--release` flag is required to build optimised high performance code.
 Without that flag the performance will be significantly worse.
 
-## Documentation
+Alternatively, you may build the executable with
+```console
+cargo build --release
+```
+and then run it with
+```
+target/release/pointsource_algs
+```
 
-The integrated documentation may be built and opened with
-```sh
-$ carg doc              # build dependency docs
-$ . misc/doc-alias.sh   # load KaTeX helper macro
-$ cargo-d --open        # build and open KaTeX-aware docs for this crate
+### Documentation
+
+Use the `--help` option to get an extensive listing of command line options.
+If using `cargo` to run the executable, you have to pass any arguments to this
+program after a double-dash:
+```console
+cargo run --release -- --help
 ```
-The `cargo-d` alias ensures that KaTeX mathematics is rendered in the generated documentation. `Rustdoc` is obsolete rubbish that does not support modern markdown featues, so `cargo doc` does not render mathematics. Instead an ugly workaround is needed.
+
+## Internals
 
-  [alg_tools]: https://tuomov.iki.fi/software/alg_tools/
-  [Rust]: https://www.rust-lang.org/
-  [gsl]: https://www.gnu.org/software/gsl/
-  [Homebrew]: https://brew.sh
+If you are interested in the program internals, the integrated source code
+documentation may be built and opened with
+```console
+cargo doc              # build dependency docs
+misc/cargo-d --open    # build and open KaTeX-aware docs for this crate
+```
+The `cargo-d` script ensures that KaTeX mathematics is rendered in the
+generated documentation. Unfortunately, `rustdoc`, akin to Rust largely itself,
+is stuck in 80's 7-bit gringo ASCII world, and does not support modern markdown
+features, such as mathematics. Instead, to render mathematics, an ugly
+workaround is needed together with lots of painful raw HTML escapes in the
+documentation.
 
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build.rs	Thu Dec 01 23:37:14 2022 +0200
@@ -0,0 +1,38 @@
+use std::env;
+use regex::{Regex, Captures};
+
+fn proc<A : AsRef<str>>(re : &str, str : A) -> String {
+    let need_to_escape = Regex::new(r"([_*\\])").unwrap();
+    Regex::new(re).unwrap().replace_all(str.as_ref(), |caps : &Captures| {
+        format!("{}{}{}",
+            caps.get(1).unwrap().as_str(),
+            need_to_escape.replace_all(caps.get(2).unwrap().as_str(), "\\$1"),
+            caps.get(3).unwrap().as_str()
+        )
+    }).to_string()
+}
+
+fn main() {
+    let out_dir = env::var("OUT_DIR").unwrap();
+    
+    // Since rust is stuck in 80's 7-bit gringo ASCII world, so that rustdoc does not support
+    // markdown KaTeX mathematics, we have to process the README to include horrible horrible
+    // horrible escapes for the math, and then use an vomit-inducingly ugly javasccript
+    // workaround to process the math on the fly.
+
+    println!("cargo:rerun-if-changed=README.md");
+
+    let readme = std::fs::read_to_string("README.md")
+        .expect("Error reading README");
+
+    // Escape _, *, and \ in equations.
+    let readme_uglified = proc(r"(?m)([^$]\$)([^$]+)(\$[^$])",
+                               proc(r"([^$]\$\$)([^$]+)(\$\$[^$])", readme));
+    // Remove the instructions for building the documentation
+    let readme_cut = Regex::new("## Internals(.*|\n)*")
+        .unwrap()
+        .replace_all(&readme_uglified, "");
+
+    std::fs::write(out_dir + "/README_uglified.md", readme_cut.as_bytes())
+        .expect("Error saving uglified README");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/cargo-d	Thu Dec 01 23:37:14 2022 +0200
@@ -0,0 +1,4 @@
+#!/bin/sh
+RUSTDOCFLAGS="--html-in-header misc/katex-header.html" cargo d --no-deps "$@"
+
+ 
\ No newline at end of file
--- a/misc/doc_alias.sh	Thu Dec 01 23:46:09 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-# source this file. use cargo rustdoc or cargo d --no-deps no build the documentation.
-echo 'Creating cargo-d alias'
-alias cargo-d='RUSTDOCFLAGS="--html-in-header misc/katex-header.html" BROWSER=/Applications/Firefox.app/Contents/MacOS/firefox-bin cargo d --no-deps'
-
- 
\ No newline at end of file
--- a/src/main.rs	Thu Dec 01 23:46:09 2022 +0200
+++ b/src/main.rs	Thu Dec 01 23:37:14 2022 +0200
@@ -1,15 +1,16 @@
 // The main documentation is in the README.
-#![doc = include_str!("../README.md")]
+// We need to uglify it in build.rs because rustdoc is stuck in the past.
+#![doc = include_str!(concat!(env!("OUT_DIR"), "/README_uglified.md"))]
 
 // We use unicode. We would like to use much more of it than Rust allows.
 // Live with it. Embrace it.
 #![allow(uncommon_codepoints)]
 #![allow(mixed_script_confusables)]
 #![allow(confusable_idents)]
-// Linear operators may be writtten e.g. as `opA` for a resemblance
-// to mathematical convention.
+// Linear operators may be written e.g. as `opA`, to keep the capital letters of mathematical
+// convention while referring to the type (trait) of the operator as `A`.
 #![allow(non_snake_case)]
-// We need the drain filter for inertial prune
+// We need the drain filter for inertial prune.
 #![feature(drain_filter)]
 
 use clap::Parser;

mercurial