---
title: Slotifier
-copyright: 2019 Nick Bowler
+copyright: 2021 Nick Bowler
license: gpl-3 or (at your option) any later version
+module: slotifier
---
-Slotifier is a simple program which takes an Excellon drill file input,
-searches for overlapping drill hits, and generates a new drill file with
-those hits converted to a single slot (G85 entry in the drill file).
-
-This is useful when using a PCB tool which does not generate such slots
-directly, but you require this format for fabrication. Simply use overlapping
-drill hits in the PCB tool to represent slots, then run slotifier on the drill
-file before sending to the fab.
-
-The types of slots that can be produced with this tool are limited: they must
-be straight lines and must have the same thickness throughout. Slotifier uses
-a simple heuristic to convert holes to slots, and might behave unexpectedly if
-drill hits overlap in complex ways, see below.
-
-# Obtaining slotifier
-
-[slotifier-gitweb]: //git.draconx.ca/gitweb/slotifier.git
-
-There are presently no released versions of slotifier. The development
-sources [may be browsed online][slotifier-gitweb] or cloned directly using
-git, e.g.,
-
-<kbd>git clone https://git.draconx.ca/slotifier.git</kbd>
-
-# Dependencies
-
-[gerbv-homepage]: http://gerbv.geda-project.org/
-[neartree-homepage]: http://neartree.sourceforge.net/
-[gettext-homepage]: https://www.gnu.org/software/gettext/
-
-Slotifier is written in C, so a working C compiler is required.
-
-The [libgerbv library][gerbv-homepage] is used to process the Excellon drill
-file format. It must be a sufficiently recent version with support for G85
-slots: the first version to support such slots is gerbv 2.7.
-
-Furthermore, to compute the overlap relation, slotifier uses the [CNearTree
-library][neartree-homepage].
-
-Optionally, in order to support localized program messages the [GNU libintl
-library][gettext-homepage] (included with the GNU C library) is required.
-
-Building from the development sources may require additional build tools.
-
-# Theory of operation
-
-Slotifier works by locating groups of drill hits which are considered
-mergeable. Two holes are considered to _overlap_ if and only if the centre of
-either hole is positioned within the other hole, and the transitive closure of
-this overlap relation gives the _mergeable_ relation. Thus, holes A and B
-are mergeable if there is some sequence of overlapping holes, starting from
-A, which leads to B.
-
-The mergeable property is an equivalence relation on the holes, so the holes
-can be partitioned into equivalence classes. Every such class with more than
-one hole in it is then converted into a slot as follows:
-
-* Two holes are chosen from the class such that the straight-line distance
- between their centres is maximized. These two centres are used as the
- endpoints of the slot.
-
-* The tool with the greatest diameter from all the holes in the class is used
- as the tool for the slot.
-
-In either case, it is unspecified which option is chosen when there is more
-than one maximum.
-
-For best results, the designer should ensure that mergeable holes form an
-approximate straight line and use the same tools.
-
-# License
-
-Slotifier is free software: you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation, either version 3 of the License or (at your option) any later
-version.
+<%= project_readme %>
--- /dev/null
+# Nick's web site: Generate a project page from a submodule README.md
+#
+# Copyright © 2021 Nick Bowler
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+def project_readme(item = @item)
+ tag = item.fetch(:release, "HEAD")
+ shortname = item.fetch(:shortname, item[:title].downcase)
+
+ data, status = Open3.capture2("git", "submodule", "foreach", "--quiet",
+ "case $sm_path in */" + item[:module] + ")" +
+ "git remote get-url origin || echo;" +
+ "git show " + tag + ":README.md ;;" +
+ "esac")
+ raise "git submodule foreach failed" if status != 0
+
+ gituri, contents = data.split("\n", 2)
+ intro, contents = contents.split("#", 2)
+ contents = if contents.nil? then "" else "\n#" + contents end
+
+ gitweb = gituri.sub(%r{^[^/]*(.*)(/.*)}, '\1/gitweb\2')
+
+ obtaining = <<~EOF
+ # Obtaining #{item[:title]}
+ EOF
+
+ if item[:release].nil?
+ obtaining += <<~EOF
+ There are presently no released versions of #{shortname}.
+ EOF
+ else
+ # TODO
+ end
+
+ obtaining += <<~EOF
+ The latest development sources [may be browsed online](#{gitweb}) or
+ cloned directly using git, e.g.,
+
+ <kbd>git clone #{gituri}</kbd>
+ EOF
+
+ return intro + obtaining + contents
+end