about summary refs log tree commit diff
path: root/nixpkgs/pkgs/tools/text
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/tools/text')
-rw-r--r--nixpkgs/pkgs/tools/text/a2ps/default.nix50
-rw-r--r--nixpkgs/pkgs/tools/text/agrep/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/aha/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/align/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/amber/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/angle-grinder/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/ansifilter/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/ascii/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/asciigraph/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/boxes/default.nix47
-rw-r--r--nixpkgs/pkgs/tools/text/catdoc/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/catdocx/default.nix31
-rw-r--r--nixpkgs/pkgs/tools/text/cconv/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/chars/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/choose/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/chroma/default.nix42
-rw-r--r--nixpkgs/pkgs/tools/text/cmigemo/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/cmigemo/no-http-tool-check.patch23
-rw-r--r--nixpkgs/pkgs/tools/text/codesearch/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/colordiff/default.nix36
-rw-r--r--nixpkgs/pkgs/tools/text/coloursum/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/convertlit/default.nix37
-rw-r--r--nixpkgs/pkgs/tools/text/copyright-update/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/crowdin-cli/default.nix45
-rw-r--r--nixpkgs/pkgs/tools/text/csview/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/csvkit/default.nix42
-rw-r--r--nixpkgs/pkgs/tools/text/dadadodo/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/dcs/default.nix46
-rw-r--r--nixpkgs/pkgs/tools/text/dfmt/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/diction/default.nix23
-rw-r--r--nixpkgs/pkgs/tools/text/diffr/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/diffstat/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/difftastic/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/diffutils/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/dirdiff/default.nix59
-rw-r--r--nixpkgs/pkgs/tools/text/dirdiff/dirdiff-2.1-vars.patch32
-rw-r--r--nixpkgs/pkgs/tools/text/discount/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/discount/fix-configure-path.patch12
-rw-r--r--nixpkgs/pkgs/tools/text/dos2unix/default.nix23
-rw-r--r--nixpkgs/pkgs/tools/text/each/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/ebook-tools/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/enca/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/enscript/default.nix44
-rw-r--r--nixpkgs/pkgs/tools/text/epubcheck/default.nix41
-rw-r--r--nixpkgs/pkgs/tools/text/esh/default.nix40
-rw-r--r--nixpkgs/pkgs/tools/text/fanficfare/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/fastmod/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/frangipanni/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/fst/0001-cargo-lockfile.patch900
-rw-r--r--nixpkgs/pkgs/tools/text/fst/default.nix45
-rw-r--r--nixpkgs/pkgs/tools/text/gawk/default.nix77
-rw-r--r--nixpkgs/pkgs/tools/text/gawk/gawk-with-extensions.nix13
-rw-r--r--nixpkgs/pkgs/tools/text/gawk/gawkextlib.nix149
-rw-r--r--nixpkgs/pkgs/tools/text/gawk/setup-hook.sh6
-rw-r--r--nixpkgs/pkgs/tools/text/gist/default.nix17
-rw-r--r--nixpkgs/pkgs/tools/text/gjo/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/glogg/default.nix41
-rw-r--r--nixpkgs/pkgs/tools/text/gnugrep/default.nix67
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/Allow_input_files_to_be_missing_for_ed-style_patches.patch33
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-1000156.patch211
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6951.patch28
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6952.patch28
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13636.patch108
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13638-and-CVE-2018-20969.patch38
-rw-r--r--nixpkgs/pkgs/tools/text/gnupatch/default.nix59
-rw-r--r--nixpkgs/pkgs/tools/text/gnused/422.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/gnused/default.nix38
-rw-r--r--nixpkgs/pkgs/tools/text/gpt2tc/0001-add-python-shebang.patch10
-rw-r--r--nixpkgs/pkgs/tools/text/gpt2tc/default.nix44
-rw-r--r--nixpkgs/pkgs/tools/text/grin/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/grip-search/default.nix31
-rw-r--r--nixpkgs/pkgs/tools/text/groff/0001-Fix-cross-compilation-by-looking-for-ar.patch46
-rw-r--r--nixpkgs/pkgs/tools/text/groff/default.nix134
-rw-r--r--nixpkgs/pkgs/tools/text/groff/site.tmac19
-rw-r--r--nixpkgs/pkgs/tools/text/gtranslator/default.nix76
-rw-r--r--nixpkgs/pkgs/tools/text/gucci/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/gucci/deps.nix30
-rw-r--r--nixpkgs/pkgs/tools/text/hck/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/highlight/default.nix58
-rw-r--r--nixpkgs/pkgs/tools/text/hottext/default.nix46
-rw-r--r--nixpkgs/pkgs/tools/text/html-tidy/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/html2text/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/hyx/default.nix30
-rw-r--r--nixpkgs/pkgs/tools/text/icdiff/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/invoice2data/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/ispell/default.nix38
-rw-r--r--nixpkgs/pkgs/tools/text/jbofihe/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/jsawk/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/jumanpp/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/kakasi/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/kdiff3/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/kytea/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/kytea/gcc-O3.patch13
-rw-r--r--nixpkgs/pkgs/tools/text/l2md/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/languagetool/default.nix38
-rw-r--r--nixpkgs/pkgs/tools/text/ledger2beancount/default.nix59
-rw-r--r--nixpkgs/pkgs/tools/text/link-grammar/default.nix65
-rw-r--r--nixpkgs/pkgs/tools/text/lv/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/m2r/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/mairix/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/mairix/mmap.patch161
-rw-r--r--nixpkgs/pkgs/tools/text/mark/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/markdown-pp/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/mawk/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/mb2md/default.nix38
-rw-r--r--nixpkgs/pkgs/tools/text/mdbook-mermaid/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/mdbook/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/mdcat/default.nix56
-rw-r--r--nixpkgs/pkgs/tools/text/mecab/base.nix16
-rw-r--r--nixpkgs/pkgs/tools/text/mecab/default.nix20
-rw-r--r--nixpkgs/pkgs/tools/text/mecab/ipadic.nix18
-rw-r--r--nixpkgs/pkgs/tools/text/mecab/nodic.nix8
-rw-r--r--nixpkgs/pkgs/tools/text/miller/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/mir-qualia/default.nix21
-rw-r--r--nixpkgs/pkgs/tools/text/mpage/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/data/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/libbtree/default.nix21
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/libfacet/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/libmtquery/default.nix31
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/libmtsupport/default.nix21
-rw-r--r--nixpkgs/pkgs/tools/text/multitran/mtutils/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/namazu/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/nawk/default.nix40
-rw-r--r--nixpkgs/pkgs/tools/text/nkf/default.nix21
-rw-r--r--nixpkgs/pkgs/tools/text/num-utils/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/numdiff/default.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/odt2txt/default.nix23
-rw-r--r--nixpkgs/pkgs/tools/text/opencc/default.nix36
-rwxr-xr-xnixpkgs/pkgs/tools/text/papertrail/Gemfile4
-rw-r--r--nixpkgs/pkgs/tools/text/papertrail/Gemfile.lock17
-rw-r--r--nixpkgs/pkgs/tools/text/papertrail/default.nix30
-rw-r--r--nixpkgs/pkgs/tools/text/papertrail/gemset.nix26
-rw-r--r--nixpkgs/pkgs/tools/text/par/default.nix42
-rw-r--r--nixpkgs/pkgs/tools/text/patchutils/0.3.3.nix7
-rw-r--r--nixpkgs/pkgs/tools/text/patchutils/default.nix6
-rw-r--r--nixpkgs/pkgs/tools/text/patchutils/drop-comments.patch84
-rw-r--r--nixpkgs/pkgs/tools/text/patchutils/generic.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/pbgopy/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/peco/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/pinyin-tool/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/platinum-searcher/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/platinum-searcher/deps.nix83
-rw-r--r--nixpkgs/pkgs/tools/text/pn/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/podiff/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/poedit/default.nix48
-rw-r--r--nixpkgs/pkgs/tools/text/popfile/default.nix60
-rw-r--r--nixpkgs/pkgs/tools/text/proselint/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/qgrep/default.nix40
-rw-r--r--nixpkgs/pkgs/tools/text/qprint/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/qshowdiff/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/reckon/Gemfile2
-rw-r--r--nixpkgs/pkgs/tools/text/reckon/Gemfile.lock19
-rw-r--r--nixpkgs/pkgs/tools/text/reckon/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/reckon/gemset.nix43
-rw-r--r--nixpkgs/pkgs/tools/text/recode/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/replace/default.nix30
-rw-r--r--nixpkgs/pkgs/tools/text/replace/malloc.patch13
-rw-r--r--nixpkgs/pkgs/tools/text/rgxg/default.nix18
-rw-r--r--nixpkgs/pkgs/tools/text/ripgrep-all/default.nix63
-rw-r--r--nixpkgs/pkgs/tools/text/ripgrep/default.nix56
-rw-r--r--nixpkgs/pkgs/tools/text/robodoc/default.nix48
-rw-r--r--nixpkgs/pkgs/tools/text/rosie/default.nix47
-rw-r--r--nixpkgs/pkgs/tools/text/rpl/default.nix23
-rw-r--r--nixpkgs/pkgs/tools/text/rs/default.nix52
-rw-r--r--nixpkgs/pkgs/tools/text/rst2html5/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile2
-rw-r--r--nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile.lock24
-rw-r--r--nixpkgs/pkgs/tools/text/ruby-zoom/default.nix18
-rw-r--r--nixpkgs/pkgs/tools/text/ruby-zoom/gemset.nix64
-rw-r--r--nixpkgs/pkgs/tools/text/runiq/default.nix20
-rw-r--r--nixpkgs/pkgs/tools/text/ruplacer/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/rust-petname/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/sad/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/schema2ldif/default.nix33
-rw-r--r--nixpkgs/pkgs/tools/text/sd/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/sgml/jade/default.nix39
-rw-r--r--nixpkgs/pkgs/tools/text/sgml/openjade/default.nix27
-rw-r--r--nixpkgs/pkgs/tools/text/sgml/openjade/msggen.patch34
-rw-r--r--nixpkgs/pkgs/tools/text/sgml/opensp/default.nix48
-rw-r--r--nixpkgs/pkgs/tools/text/sgml/opensp/setup-hook.sh22
-rw-r--r--nixpkgs/pkgs/tools/text/shab/default.nix73
-rw-r--r--nixpkgs/pkgs/tools/text/shfmt/default.nix37
-rw-r--r--nixpkgs/pkgs/tools/text/shocco/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/sift/default.nix25
-rw-r--r--nixpkgs/pkgs/tools/text/sift/deps.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/silver-searcher/bash-completion.patch5
-rw-r--r--nixpkgs/pkgs/tools/text/silver-searcher/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/smu/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/snippetpixie/default.nix92
-rw-r--r--nixpkgs/pkgs/tools/text/source-highlight/default.nix53
-rw-r--r--nixpkgs/pkgs/tools/text/tab/default.nix40
-rw-r--r--nixpkgs/pkgs/tools/text/transifex-client/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/tv/default.nix23
-rw-r--r--nixpkgs/pkgs/tools/text/txt2tags/default.nix35
-rw-r--r--nixpkgs/pkgs/tools/text/ucg/default.nix40
-rw-r--r--nixpkgs/pkgs/tools/text/ugrep/default.nix39
-rw-r--r--nixpkgs/pkgs/tools/text/uni2ascii/default.nix41
-rw-r--r--nixpkgs/pkgs/tools/text/unoconv/default.nix41
-rw-r--r--nixpkgs/pkgs/tools/text/unrtf/default.nix31
-rw-r--r--nixpkgs/pkgs/tools/text/untex/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/uwc/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/vale/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/vgrep/default.nix32
-rw-r--r--nixpkgs/pkgs/tools/text/wdiff/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/wgetpaste/default.nix30
-rw-r--r--nixpkgs/pkgs/tools/text/wrap/default.nix36
-rw-r--r--nixpkgs/pkgs/tools/text/xidel/default.nix93
-rw-r--r--nixpkgs/pkgs/tools/text/xml/basex/basex.svg81
-rw-r--r--nixpkgs/pkgs/tools/text/xml/basex/default.nix66
-rw-r--r--nixpkgs/pkgs/tools/text/xml/html-xml-utils/default.nix20
-rw-r--r--nixpkgs/pkgs/tools/text/xml/jing-trang/default.nix43
-rw-r--r--nixpkgs/pkgs/tools/text/xml/rnv/default.nix20
-rw-r--r--nixpkgs/pkgs/tools/text/xml/rxp/default.nix18
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xml2/default.nix22
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xmldiff/default.nix41
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xmlformat/default.nix28
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xmloscopy/default.nix53
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xmlstarlet/default.nix34
-rw-r--r--nixpkgs/pkgs/tools/text/xml/xpf/default.nix21
-rw-r--r--nixpkgs/pkgs/tools/text/xsv/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/xurls/default.nix24
-rw-r--r--nixpkgs/pkgs/tools/text/yaml-merge/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/zimwriterfs/default.nix43
-rw-r--r--nixpkgs/pkgs/tools/text/zoekt/default.nix29
-rw-r--r--nixpkgs/pkgs/tools/text/zstxtns-utils/default.nix39
225 files changed, 8837 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/tools/text/a2ps/default.nix b/nixpkgs/pkgs/tools/text/a2ps/default.nix
new file mode 100644
index 000000000000..d3fe3a7e7058
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/a2ps/default.nix
@@ -0,0 +1,50 @@
+{ lib, stdenv, fetchurl, fetchpatch, autoconf, bison, libpaper, gperf, file, perl }:
+
+stdenv.mkDerivation rec {
+  pname = "a2ps";
+  version = "4.14";
+
+  src = fetchurl {
+    url = "mirror://gnu/a2ps/a2ps-${version}.tar.gz";
+    sha256 = "195k78m1h03m961qn7jr120z815iyb93gwi159p1p9348lyqvbpk";
+  };
+
+  patches = [
+    (fetchpatch {
+      url = "https://sources.debian.net/data/main/a/a2ps/1:4.14-1.3/debian/patches/09_CVE-2001-1593.diff";
+      sha256 = "1hrfmvb21zlklmg2fqikgywhqgc4qnvbhx517w87faafrhzhlnh0";
+    })
+    (fetchpatch {
+      url = "https://sources.debian.net/data/main/a/a2ps/1:4.14-1.3/debian/patches/CVE-2014-0466.diff";
+      sha256 = "0grqqsc3m45niac56m19m5gx7gc0m8zvia5iman1l4rlq31shf8s";
+    })
+    (fetchpatch {
+      name = "CVE-2015-8107.patch";
+      url = "https://sources.debian.net/data/main/a/a2ps/1:4.14-1.3/debian/patches/fix-format-security.diff";
+      sha256 = "0pq7zl41gf2kc6ahwyjnzn93vbxb4jc2c5g8j20isp4vw6dqrnwv";
+    })
+  ];
+
+  postPatch = ''
+    substituteInPlace afm/make_fonts_map.sh --replace "/bin/rm" "rm"
+    substituteInPlace tests/defs.in --replace "/bin/rm" "rm"
+  '';
+
+  nativeBuildInputs = [ autoconf file bison perl ];
+  buildInputs = [ libpaper gperf ];
+
+  meta = with lib; {
+    description = "An Anything to PostScript converter and pretty-printer";
+    longDescription = ''
+      GNU a2ps converts files into PostScript for printing or viewing. It uses a nice default format,
+      usually two pages on each physical page, borders surrounding pages, headers with useful information
+      (page number, printing date, file name or supplied header), line numbering, symbol substitution as
+      well as pretty printing for a wide range of programming languages.
+    '';
+    homepage = "https://www.gnu.org/software/a2ps/";
+    license = licenses.gpl3Plus;
+    maintainers = [ maintainers.bennofs ];
+    platforms = platforms.linux;
+
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/agrep/default.nix b/nixpkgs/pkgs/tools/text/agrep/default.nix
new file mode 100644
index 000000000000..9fe158b426ae
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/agrep/default.nix
@@ -0,0 +1,32 @@
+{ lib, stdenv, fetchFromGitHub }:
+
+stdenv.mkDerivation {
+  pname = "agrep";
+  version = "3.41.5";
+
+  src = fetchFromGitHub {
+    owner = "Wikinaut";
+    repo = "agrep";
+    # This repository has numbered versions, but not Git tags.
+    rev = "eef20411d605d9d17ead07a0ade75046f2728e21";
+    sha256 = "14addnwspdf2mxpqyrw8b84bb2257y43g5ccy4ipgrr91fmxq2sk";
+  };
+
+  # Related: https://github.com/Wikinaut/agrep/pull/11
+  prePatch = lib.optionalString (stdenv.hostPlatform.isMusl || stdenv.isDarwin) ''
+    sed -i '1i#include <sys/stat.h>' checkfil.c newmgrep.c recursiv.c
+  '';
+  installPhase = ''
+    install -Dm 555 agrep -t "$out/bin"
+    install -Dm 444 docs/* -t "$out/doc"
+  '';
+
+  makeFlags = [ "CC=${stdenv.cc.targetPrefix}cc" ];
+
+  meta = with lib; {
+    description = "Approximate grep for fast fuzzy string searching";
+    homepage = "https://www.tgries.de/agrep/";
+    license = licenses.isc;
+    platforms = with platforms; linux ++ darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/aha/default.nix b/nixpkgs/pkgs/tools/text/aha/default.nix
new file mode 100644
index 000000000000..4ac07cef7eed
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/aha/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchFromGitHub }:
+
+stdenv.mkDerivation rec {
+  pname = "aha";
+  version = "0.5.1";
+
+  src = fetchFromGitHub {
+    sha256 = "1gywad0rvvz3c5balz8cxsnx0562hj2ngzqyr8zsy2mb4pn0lpgv";
+    rev = version;
+    repo = "aha";
+    owner = "theZiz";
+  };
+
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "ANSI HTML Adapter";
+    longDescription = ''
+      aha takes ANSI SGR-coloured input and produces W3C-conformant HTML code.
+    '';
+    homepage = "https://github.com/theZiz/aha";
+    license = with licenses; [ lgpl2Plus mpl11 ];
+    maintainers = with maintainers; [ pSub ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/align/default.nix b/nixpkgs/pkgs/tools/text/align/default.nix
new file mode 100644
index 000000000000..4f67d747da4c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/align/default.nix
@@ -0,0 +1,22 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "align";
+  version = "1.1.3";
+
+  src = fetchFromGitHub {
+    owner = "Guitarbum722";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "17gs3417633z71kc6l5zqg4b3rjhpn2v8qs8rnfrk4nbwzz4nrq3";
+  };
+
+  vendorSha256 = null;
+
+  meta = with lib; {
+    homepage = "https://github.com/Guitarbum722/align";
+    description = "A general purpose application and library for aligning text";
+    maintainers = with maintainers; [ hrhino ];
+    license = licenses.mit;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/amber/default.nix b/nixpkgs/pkgs/tools/text/amber/default.nix
new file mode 100644
index 000000000000..1cd9e74f1943
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/amber/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform
+, libiconv, Security
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "amber";
+  version = "0.5.9";
+
+  src = fetchFromGitHub {
+    owner = "dalance";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-mmgJCD7kJjvpxyagsoe5CSzqIEZcIiYMAMP3axRphv4=";
+  };
+
+  cargoSha256 = "sha256-opRinhTmhZxpAwHNiVOLXL8boQf09Y1NXrWQ6HWQYQ0=";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ libiconv Security ];
+
+  meta = with lib; {
+    description = "A code search-and-replace tool";
+    homepage = "https://github.com/dalance/amber";
+    license = with licenses; [ mit ];
+    maintainers = [ maintainers.bdesham ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/angle-grinder/default.nix b/nixpkgs/pkgs/tools/text/angle-grinder/default.nix
new file mode 100644
index 000000000000..02235b057d4d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/angle-grinder/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, fetchFromGitHub
+, rustPlatform
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "angle-grinder";
+  version = "0.17.0";
+
+  src = fetchFromGitHub {
+    owner = "rcoh";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-jG3jHFqFOrIT/e5oyLOEckw5C3LIs7amFAa4QDEI/EY=";
+  };
+
+  cargoSha256 = "sha256-Rkex+fnnacV+DCRpX3Zh9J3vGuG4QfFhFezHTs33peY=";
+
+  meta = with lib; {
+    description = "Slice and dice logs on the command line";
+    homepage = "https://github.com/rcoh/angle-grinder";
+    license = licenses.mit;
+    maintainers = with maintainers; [ bbigras ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ansifilter/default.nix b/nixpkgs/pkgs/tools/text/ansifilter/default.nix
new file mode 100644
index 000000000000..97b06b9a0c7e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ansifilter/default.nix
@@ -0,0 +1,35 @@
+{ fetchurl, lib, stdenv, pkg-config, boost, lua }:
+
+stdenv.mkDerivation rec {
+  pname = "ansifilter";
+  version = "2.18";
+
+  src = fetchurl {
+    url = "http://www.andre-simon.de/zip/ansifilter-${version}.tar.bz2";
+    sha256 = "sha256-Zs8BfTakPV9q4gYJzjtYZHSU7mwOQfxoLFmL/859fTk=";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ boost lua ];
+
+  postPatch = ''
+    substituteInPlace src/makefile --replace "CC=g++" "CC=c++"
+  '';
+
+  makeFlags = [
+    "PREFIX=${placeholder "out"}"
+    "conf_dir=/etc/ansifilter"
+  ];
+
+  meta = with lib; {
+    description = "Tool to convert ANSI to other formats";
+    longDescription = ''
+      Tool to remove ANSI or convert them to another format
+      (HTML, TeX, LaTeX, RTF, Pango or BBCode)
+    '';
+    homepage = "http://www.andre-simon.de/doku/ansifilter/en/ansifilter.php";
+    license = licenses.gpl3;
+    maintainers = [ maintainers.Adjective-Object ];
+    platforms = platforms.linux ++ platforms.darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ascii/default.nix b/nixpkgs/pkgs/tools/text/ascii/default.nix
new file mode 100644
index 000000000000..f596c8d330d2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ascii/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "ascii";
+  version = "3.18";
+
+  src = fetchurl {
+    url = "http://www.catb.org/~esr/ascii/${pname}-${version}.tar.gz";
+    sha256 = "0b87vy06s8s3a8q70pqavsbk4m4ff034sdml2xxa6qfsykaj513j";
+  };
+
+  prePatch = ''
+    sed -i -e "s|^PREFIX = .*|PREFIX = $out|" Makefile
+  '';
+
+  preInstall = ''
+    mkdir -vp "$out/bin" "$out/share/man/man1"
+  '';
+
+  meta = with lib; {
+    description = "Interactive ASCII name and synonym chart";
+    homepage = "http://www.catb.org/~esr/ascii/";
+    license = licenses.bsd3;
+    platforms = platforms.all;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/asciigraph/default.nix b/nixpkgs/pkgs/tools/text/asciigraph/default.nix
new file mode 100644
index 000000000000..27c2a1ff28ec
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/asciigraph/default.nix
@@ -0,0 +1,22 @@
+{ lib, buildGoPackage, fetchFromGitHub }:
+
+buildGoPackage rec {
+  pname = "asciigraph";
+  version = "0.5.2";
+
+  goPackagePath = "github.com/guptarohit/asciigraph";
+
+  src = fetchFromGitHub {
+    owner = "guptarohit";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-iVgJtxt0B6nMA3bieZ1CmZucwLMb5av6Wn5BMDRWfcI=";
+  };
+
+  meta = with lib; {
+    homepage = "https://github.com/guptarohit/asciigraph";
+    description = "Lightweight ASCII line graph ╭┈╯ command line app";
+    license = licenses.bsd3;
+    maintainers = [ maintainers.mmahut ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/boxes/default.nix b/nixpkgs/pkgs/tools/text/boxes/default.nix
new file mode 100644
index 000000000000..f39349b2fbf0
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/boxes/default.nix
@@ -0,0 +1,47 @@
+{ lib, stdenv, fetchFromGitHub, bison, flex }:
+
+stdenv.mkDerivation rec {
+  pname = "boxes";
+  version = "1.3";
+
+  src = fetchFromGitHub {
+    owner = "ascii-boxes";
+    repo = "boxes";
+    rev = "v${version}";
+    sha256 = "0b12rsynrmkldlwcb62drk33kk0aqwbj10mq5y5x3hjf626gjwsi";
+  };
+
+  # Building instructions:
+  # https://boxes.thomasjensen.com/build.html#building-on-linux--unix
+  nativeBuildInputs = [ bison flex ];
+
+  dontConfigure = true;
+
+  # Makefile references a system wide config file in '/usr/share'. Instead, we
+  # move it within the store by default.
+  preBuild = ''
+    substituteInPlace Makefile \
+      --replace "GLOBALCONF = /usr/share/boxes" \
+                "GLOBALCONF=${placeholder "out"}/share/boxes/boxes-config"
+  '';
+
+  makeFlags = [ "CC=${stdenv.cc.targetPrefix}cc" ];
+
+  installPhase = ''
+    install -Dm755 -t $out/bin src/boxes
+    install -Dm644 -t $out/share/boxes boxes-config
+    install -Dm644 -t $out/share/man/man1 doc/boxes.1
+  '';
+
+  meta = with lib; {
+    description = "Command line ASCII boxes unlimited!";
+    longDescription = ''
+      Boxes is a command line filter program that draws ASCII art boxes around
+      your input text.
+    '';
+    homepage = "https://boxes.thomasjensen.com";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ waiting-for-dev ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/catdoc/default.nix b/nixpkgs/pkgs/tools/text/catdoc/default.nix
new file mode 100644
index 000000000000..db57243efdc2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/catdoc/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl, fetchpatch }:
+
+stdenv.mkDerivation rec {
+  pname = "catdoc";
+  version = "0.95";
+
+  src = fetchurl {
+    url = "http://ftp.wagner.pp.ru/pub/catdoc/${pname}-${version}.tar.gz";
+    sha256 = "514a84180352b6bf367c1d2499819dfa82b60d8c45777432fa643a5ed7d80796";
+  };
+
+  patches = [
+    (fetchpatch {
+      url = "https://sources.debian.org/data/main/c/catdoc/1:0.95-4.1/debian/patches/05-CVE-2017-11110.patch";
+      sha256 = "1ljnwvssvzig94hwx8843b88p252ww2lbxh8zybcwr3kwwlcymx7";
+    })
+  ];
+
+  # Remove INSTALL file to avoid `make` misinterpreting it as an up-to-date
+  # target on case-insensitive filesystems e.g. Darwin
+  preInstall = ''
+    rm -v INSTALL
+  '';
+
+  configureFlags = [ "--disable-wordview" ];
+
+  meta = with lib; {
+    description = "MS-Word/Excel/PowerPoint to text converter";
+    platforms = platforms.all;
+    license = licenses.gpl2;
+    maintainers = with maintainers; [];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/catdocx/default.nix b/nixpkgs/pkgs/tools/text/catdocx/default.nix
new file mode 100644
index 000000000000..c762e15c80e2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/catdocx/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, lib, fetchFromGitHub, makeWrapper, unzip, catdoc }:
+
+stdenv.mkDerivation {
+  pname = "catdocx";
+  version = "unstable-2017-01-02";
+
+  src = fetchFromGitHub {
+    owner = "jncraton";
+    repo = "catdocx";
+    rev = "04fa0416ec1f116d4996685e219f0856d99767cb";
+    sha256 = "1sxiqhkvdqn300ygfgxdry2dj2cqzjhkzw13c6349gg5vxfypcjh";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  installPhase = ''
+    mkdir -p $out/libexec $out/bin
+    cp catdocx.sh $out/libexec
+    chmod +x $out/libexec/catdocx.sh
+    wrapProgram $out/libexec/catdocx.sh --prefix PATH : "${lib.makeBinPath [ unzip catdoc ]}"
+    ln -s $out/libexec/catdocx.sh $out/bin/catdocx
+  '';
+
+  meta = with lib; {
+    description = "Extracts plain text from docx files";
+    homepage = "https://github.com/jncraton/catdocx";
+    license = with licenses; [ bsd3 ];
+    maintainers = [ maintainers.michalrus ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/cconv/default.nix b/nixpkgs/pkgs/tools/text/cconv/default.nix
new file mode 100644
index 000000000000..e918d620c678
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/cconv/default.nix
@@ -0,0 +1,22 @@
+{ lib, stdenv, fetchurl, autoreconfHook, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "cconv";
+  version = "0.6.3";
+
+  src = fetchurl {
+    url = "https://github.com/xiaoyjy/cconv/archive/v${version}.tar.gz";
+    sha256 = "82f46a94829f5a8157d6f686e302ff5710108931973e133d6e19593061b81d84";
+  };
+
+  nativeBuildInputs = [ autoreconfHook ];
+  buildInputs = [ libiconv ];
+
+  meta = with lib; {
+    description = "A iconv based simplified-traditional chinese conversion tool";
+    homepage = "https://github.com/xiaoyjy/cconv";
+    license = licenses.mit;
+    platforms = platforms.all;
+    maintainers = [ maintainers.redfish64 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/chars/default.nix b/nixpkgs/pkgs/tools/text/chars/default.nix
new file mode 100644
index 000000000000..c8d1b1064acd
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/chars/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv
+, fetchFromGitHub
+, rustPlatform
+, Security
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "chars";
+  version = "0.5.0";
+
+  src = fetchFromGitHub {
+    owner = "antifuchs";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "1pyda3b6svxzc98d7ggl7v9xd0xhilmpjrnajzh77zcwzq42s17l";
+  };
+
+  cargoSha256 = "0ywywbcnc9jm0cfd6kbq8vl6r5dl16sxn7pwi2k6l0sj75pm1i6h";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ Security ];
+
+  meta = with lib; {
+    description = "Commandline tool to display information about unicode characters";
+    homepage = "https://github.com/antifuchs/chars";
+    license = licenses.mit;
+    maintainers = with maintainers; [ bbigras ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/choose/default.nix b/nixpkgs/pkgs/tools/text/choose/default.nix
new file mode 100644
index 000000000000..b214c65b534c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/choose/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, fetchFromGitHub
+, rustPlatform
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "choose";
+  version = "1.3.3";
+
+  src = fetchFromGitHub {
+    owner = "theryangeary";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-HYwlAgFKbi6or2eblERdMMjJOJdtt2FCQECUg3MzO8E=";
+  };
+
+  cargoSha256 = "sha256-55/B+LxdbekfaKKyng0lUCU3QnqL34M+QnLUxaPqkqI=";
+
+  meta = with lib; {
+    description = "A human-friendly and fast alternative to cut and (sometimes) awk";
+    homepage = "https://github.com/theryangeary/choose";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ sohalt ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/chroma/default.nix b/nixpkgs/pkgs/tools/text/chroma/default.nix
new file mode 100644
index 000000000000..1b9cbcd3727a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/chroma/default.nix
@@ -0,0 +1,42 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "chroma";
+  version = "0.9.2";
+
+  src = fetchFromGitHub {
+    owner  = "alecthomas";
+    repo   = pname;
+    rev    = "v${version}";
+    sha256 = "19d7yr6q8kwrm91yyglmw9n7wa861sgi6dbwn8sl6dp55czfwvaq";
+    # populate values otherwise taken care of by goreleaser,
+    # unfortunately these require us to use git. By doing
+    # this in postFetch we can delete .git afterwards and
+    # maintain better reproducibility of the src.
+    leaveDotGit = true;
+    postFetch = ''
+      cd "$out"
+
+      commit="$(git rev-parse HEAD)"
+      date=$(git show -s --format=%aI "$commit")
+
+      substituteInPlace "$out/cmd/chroma/main.go" \
+        --replace 'version = "?"' 'version = "${version}"' \
+        --replace 'commit  = "?"' "commit = \"$commit\"" \
+        --replace 'date    = "?"' "date = \"$date\""
+
+      find "$out" -name .git -print0 | xargs -0 rm -rf
+    '';
+  };
+
+  vendorSha256 = "0y8mp08zccn9qxrsj9j7vambz8dwzsxbbgrlppzam53rg8rpxhrg";
+
+  subPackages = [ "cmd/chroma" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/alecthomas/chroma";
+    description = "A general purpose syntax highlighter in pure Go";
+    license = licenses.mit;
+    maintainers = [ maintainers.sternenseemann ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/cmigemo/default.nix b/nixpkgs/pkgs/tools/text/cmigemo/default.nix
new file mode 100644
index 000000000000..6787d68991d3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/cmigemo/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchFromGitHub, fetchurl, gzip, libiconv, nkf, perl, skk-dicts, which }:
+
+stdenv.mkDerivation {
+  pname = "cmigemo";
+  version = "1.3e";
+
+  src = fetchFromGitHub {
+    owner = "koron";
+    repo = "cmigemo";
+    rev = "5c014a885972c77e67d0d17d367d05017c5873f7";
+    sha256 = "0xrblwhaf70m0knkd5584iahaq84rlk0926bhdsrzmakpw77hils";
+  };
+
+  nativeBuildInputs = [ gzip libiconv nkf perl which ];
+
+  postUnpack = ''
+    cp ${skk-dicts}/share/SKK-JISYO.L source/dict/
+  '';
+
+  patches = [ ./no-http-tool-check.patch ];
+
+  makeFlags = [ "INSTALL=install" ];
+
+  buildPhase = if stdenv.isDarwin then "make osx-all" else "make gcc-all";
+
+  installTargets = [ (if stdenv.isDarwin then "osx-install" else "gcc-install") ];
+
+  meta = with lib; {
+    description = "A tool that supports Japanese incremental search with Romaji";
+    homepage = "https://www.kaoriya.net/software/cmigemo";
+    license = licenses.mit;
+    maintainers = [ maintainers.cohei ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/cmigemo/no-http-tool-check.patch b/nixpkgs/pkgs/tools/text/cmigemo/no-http-tool-check.patch
new file mode 100644
index 000000000000..518bfa0e6171
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/cmigemo/no-http-tool-check.patch
@@ -0,0 +1,23 @@
+diff --git a/configure b/configure
+index 4480261..2fb9b34 100755
+--- a/configure
++++ b/configure
+@@ -28,18 +28,6 @@ do
+   esac
+ done
+ 
+-# Check HTTP access tool
+-if CHECK_COMMAND curl ; then
+-  PROGRAM_HTTP="curl -O"
+-elif CHECK_COMMAND wget ; then
+-  PROGRAM_HTTP="wget"
+-elif CHECK_COMMAND fetch ; then
+-  PROGRAM_HTTP="fetch"
+-else
+-  echo "ERROR: Require one of HTTP access tools (curl, wget or fetch)."
+-  exit 1
+-fi
+-
+ # Check encoding filter
+ if CHECK_COMMAND qkc ; then
+   PROGRAM_ENCODEFILTER="qkc -q -u"
diff --git a/nixpkgs/pkgs/tools/text/codesearch/default.nix b/nixpkgs/pkgs/tools/text/codesearch/default.nix
new file mode 100644
index 000000000000..9c3e9fbd8409
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/codesearch/default.nix
@@ -0,0 +1,24 @@
+# This file was generated by go2nix.
+{ lib, buildGoPackage, fetchgit }:
+
+buildGoPackage rec {
+  pname = "codesearch";
+  version = "20150717-${lib.strings.substring 0 7 rev}";
+  rev = "a45d81b686e85d01f2838439deaf72126ccd5a96";
+
+  goPackagePath = "github.com/google/codesearch";
+
+  src = fetchgit {
+    inherit rev;
+    url = "https://github.com/google/codesearch";
+    sha256 = "12bv3yz0l3bmsxbasfgv7scm9j719ch6pmlspv4bd4ix7wjpyhny";
+  };
+
+  meta = {
+    description = "Fast, indexed regexp search over large file trees";
+    homepage = "https://github.com/google/codesearch";
+    license = [ lib.licenses.bsd3 ];
+    maintainers = [ lib.maintainers.bennofs ];
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/colordiff/default.nix b/nixpkgs/pkgs/tools/text/colordiff/default.nix
new file mode 100644
index 000000000000..364d3c6edc45
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/colordiff/default.nix
@@ -0,0 +1,36 @@
+{ lib, stdenv, fetchFromGitHub, docbook_xml_dtd_412, docbook_xsl, perl, w3m, xmlto }:
+
+stdenv.mkDerivation rec {
+  pname = "colordiff";
+  version = "1.0.19";
+
+  src = fetchFromGitHub {
+    owner = "daveewart";
+    repo = "colordiff";
+    rev = "v${version}";
+    sha256 = "1v7s1yn0qvn08iwm5js8mxn442392qyr7s9ij506byfd497ag7qk";
+  };
+
+  nativeBuildInputs = [ docbook_xml_dtd_412 docbook_xsl perl w3m xmlto ];
+
+  buildInputs = [ perl ];
+
+  postPatch = ''
+    substituteInPlace Makefile \
+      --replace 'TMPDIR=colordiff-''${VERSION}' ""
+  '';
+
+  installFlags = [
+    "INSTALL_DIR=/bin"
+    "MAN_DIR=/share/man/man1"
+    "DESTDIR=${placeholder "out"}"
+  ];
+
+  meta = with lib; {
+    description = "Wrapper for 'diff' that produces the same output but with pretty 'syntax' highlighting";
+    homepage = "https://www.colordiff.org/";
+    license = licenses.gpl2Plus;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ SuperSandro2000 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/coloursum/default.nix b/nixpkgs/pkgs/tools/text/coloursum/default.nix
new file mode 100644
index 000000000000..8391b75a67bc
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/coloursum/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, Security }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "coloursum";
+  version = "0.2.0";
+
+  src = fetchFromGitHub {
+    owner = "ticky";
+    repo = "coloursum";
+    rev = "v${version}";
+    sha256 = "1piz0l7qdcvjzfykm6rzqc8s1daxp3cj3923v9cmm41bc2v0p5q0";
+  };
+
+  cargoSha256 = "08l01ivmln9gwabwa1p0gk454qyxlcpnlxx840vys476f4pw7vvf";
+
+  buildInputs = lib.optional stdenv.isDarwin Security;
+
+  meta = with lib; {
+    description = "Colourise your checksum output";
+    homepage = "https://github.com/ticky/coloursum";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fgaz ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/convertlit/default.nix b/nixpkgs/pkgs/tools/text/convertlit/default.nix
new file mode 100644
index 000000000000..4225934d2d4e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/convertlit/default.nix
@@ -0,0 +1,37 @@
+{lib, stdenv, fetchzip, libtommath}:
+
+stdenv.mkDerivation rec {
+  pname = "convertlit";
+  version = "1.8";
+
+  src = fetchzip {
+    url = "http://www.convertlit.com/convertlit${lib.replaceStrings ["."] [""] version}src.zip";
+    sha256 = "182nsin7qscgbw2h92m0zadh3h8q410h5cza6v486yjfvla3dxjx";
+    stripRoot = false;
+  };
+
+  buildInputs = [libtommath];
+
+  hardeningDisable = [ "format" ];
+
+  buildPhase = ''
+    cd lib
+    make
+    cd ../clit18
+    substituteInPlace Makefile \
+      --replace ../libtommath-0.30/libtommath.a -ltommath
+    make
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp clit $out/bin
+  '';
+
+  meta = {
+    homepage = "http://www.convertlit.com/";
+    description = "A tool for converting Microsoft Reader ebooks to more open formats";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/copyright-update/default.nix b/nixpkgs/pkgs/tools/text/copyright-update/default.nix
new file mode 100644
index 000000000000..e0318c20a0e6
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/copyright-update/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchFromGitHub, perl }:
+
+stdenv.mkDerivation rec {
+  pname = "copyright-update";
+  version = "2016.1018";
+
+  src = fetchFromGitHub {
+    name = "${pname}-${version}-src";
+    owner = "jaalto";
+    repo = "project--copyright-update";
+    rev = "release/${version}";
+    sha256 = "1kj6jlgyxrgvrpv7fcgbibfqqa83xljp17v6sas42dlb105h6sgd";
+  };
+
+  buildInputs = [ perl ];
+
+  installFlags = [ "INSTALL=install" "prefix=$(out)" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/jaalto/project--copyright-update";
+    description = "Updates the copyright information in a set of files";
+    license = licenses.gpl2Plus;
+    platforms = platforms.all;
+    maintainers = [ maintainers.rycee ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/crowdin-cli/default.nix b/nixpkgs/pkgs/tools/text/crowdin-cli/default.nix
new file mode 100644
index 000000000000..f5c489681e93
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/crowdin-cli/default.nix
@@ -0,0 +1,45 @@
+{ lib
+, stdenv
+, fetchurl
+, gawk
+, git
+, gnugrep
+, installShellFiles
+, jre
+, makeWrapper
+, unzip
+}:
+
+stdenv.mkDerivation rec {
+  pname = "crowdin-cli";
+  version = "3.7.0";
+
+  src = fetchurl {
+    url = "https://github.com/crowdin/${pname}/releases/download/${version}/${pname}.zip";
+    sha256 = "sha256-2TQL5k2ndckFjOOXNz7clVpwPUMStR4xgd1P+qUhNC8=";
+  };
+
+  nativeBuildInputs = [ installShellFiles makeWrapper unzip ];
+
+  installPhase = ''
+    runHook preInstall
+
+    install -D crowdin-cli.jar $out/lib/crowdin-cli.jar
+
+    installShellCompletion --cmd crowdin --bash ./crowdin_completion
+
+    makeWrapper ${jre}/bin/java $out/bin/crowdin \
+      --argv0 crowdin \
+      --add-flags "-jar $out/lib/crowdin-cli.jar" \
+      --prefix PATH : ${lib.makeBinPath [ gawk gnugrep git ]}
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/crowdin/crowdin-cli/";
+    description = "A command-line client for the Crowdin API";
+    license = licenses.mit;
+    maintainers = with maintainers; [ DamienCassou ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/csview/default.nix b/nixpkgs/pkgs/tools/text/csview/default.nix
new file mode 100644
index 000000000000..60186a6b3b75
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/csview/default.nix
@@ -0,0 +1,22 @@
+{ fetchFromGitHub, lib, rustPlatform }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "csview";
+  version = "0.3.8";
+
+  src = fetchFromGitHub {
+    owner = "wfxr";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "18bz12yn85h9vj0b18iaziix9km2iwh8gwfs93fddjv6kg87p38q";
+  };
+
+  cargoSha256 = "1my6gl8zq5k7clzapgbf1mmcgq8mmdbhl250rdd1fvfd59wkrwra";
+
+  meta = with lib; {
+    description = "A high performance csv viewer with cjk/emoji support";
+    homepage = "https://github.com/wfxr/csview";
+    license = with licenses; [ mit /* or */ asl20 ];
+    maintainers = with maintainers; [ figsoda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/csvkit/default.nix b/nixpkgs/pkgs/tools/text/csvkit/default.nix
new file mode 100644
index 000000000000..56f5bae3123d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/csvkit/default.nix
@@ -0,0 +1,42 @@
+{ lib, fetchpatch, python3 }:
+
+python3.pkgs.buildPythonApplication rec {
+  pname = "csvkit";
+  version = "1.0.5";
+
+  src = python3.pkgs.fetchPypi {
+    inherit pname version;
+    sha256 = "1ffmbzk4rxnl1yhqfl58v7kvl5m9cbvjm8v7xp4mvr00sgs91lvv";
+  };
+
+  patches = [
+    # Fixes a failing dbf related test. Won't be needed on 1.0.6 or later.
+    (fetchpatch {
+      url = "https://github.com/wireservice/csvkit/commit/5f22e664121b13d9ff005a9206873a8f97431dca.patch";
+      sha256 = "1kg00z65x7l6dnm5nfsr5krs8m7mv23hhb1inkaqf5m5fpkpnvv7";
+    })
+  ];
+
+  propagatedBuildInputs = with python3.pkgs; [
+    agate
+    agate-excel
+    agate-dbf
+    agate-sql
+    six
+    setuptools
+  ];
+
+  checkInputs = with python3.pkgs; [
+    nose
+    pytestCheckHook
+  ];
+
+  pythonImportsCheck = [ "csvkit" ];
+
+  meta = with lib; {
+    description = "A suite of command-line tools for converting to and working with CSV";
+    maintainers = with maintainers; [ vrthra ];
+    license = licenses.mit;
+    homepage = "https://github.com/wireservice/csvkit";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/dadadodo/default.nix b/nixpkgs/pkgs/tools/text/dadadodo/default.nix
new file mode 100644
index 000000000000..a70a7efda72e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dadadodo/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "dadadodo";
+  version = "1.04";
+
+  src = fetchurl {
+    url = "https://www.jwz.org/dadadodo/${pname}-${version}.tar.gz";
+    sha256 = "1pzwp3mim58afjrc92yx65mmgr1c834s1v6z4f4gyihwjn8bn3if";
+  };
+
+  makeFlags = [ "CC=${stdenv.cc.targetPrefix}cc" ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp dadadodo $out/bin
+  '';
+
+  hardeningDisable = [ "format" ];
+
+  meta = with lib; {
+    description = "Markov chain-based text generator";
+    homepage = "http://www.jwz.org/dadadodo";
+    maintainers = with maintainers; [ pSub ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/dcs/default.nix b/nixpkgs/pkgs/tools/text/dcs/default.nix
new file mode 100644
index 000000000000..511931f03808
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dcs/default.nix
@@ -0,0 +1,46 @@
+{ lib
+, buildGoModule
+, fetchFromGitHub
+, yuicompressor
+, zopfli
+, stdenv
+}:
+buildGoModule {
+  pname = "dcs";
+  version = "unstable-2021-04-07";
+
+  src = fetchFromGitHub {
+    owner = "Debian";
+    repo = "dcs";
+    rev = "da46accc4d55e9bfde1a6852ac5a9e730fcbbb2c";
+    sha256 = "N+6BXlKn1YTlh0ZdPNWa0nuJNcQtlUIc9TocM8cbzQk=";
+  };
+
+  vendorSha256 = "l2mziuisx0HzuP88rS5M+Wha6lu8P036wJYZlmzjWfs=";
+
+  # Depends on dcs binaries
+  doCheck = false;
+
+  nativeBuildInputs = [
+    yuicompressor
+    zopfli
+  ];
+
+  postBuild = ''
+    make -C static -j$NIX_BUILD_CORES
+  '';
+
+  postInstall = ''
+    mkdir -p $out/share/dcs
+    cp -r cmd/dcs-web/templates $out/share/dcs
+    cp -r static $out/share/dcs
+  '';
+
+  meta = with lib; {
+    description = "Debian Code Search";
+    homepage = "https://github.com/Debian/dcs";
+    license = licenses.bsd3;
+    maintainers = teams.determinatesystems.members;
+    broken = stdenv.isAarch64;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/dfmt/default.nix b/nixpkgs/pkgs/tools/text/dfmt/default.nix
new file mode 100644
index 000000000000..16702bb69663
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dfmt/default.nix
@@ -0,0 +1,27 @@
+{ lib
+, python3
+}:
+
+let
+  inherit (python3.pkgs)
+    buildPythonApplication
+    fetchPypi
+    pythonOlder;
+in
+buildPythonApplication rec {
+  pname = "dfmt";
+  version = "1.2.0";
+  disabled = pythonOlder "3.7";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "7af6360ca8d556f1cfe82b97f03b8d1ea5a9d6de1fa3018290c844b6566d9d6e";
+  };
+
+  meta = with lib; {
+    description = "Format paragraphs, comments and doc strings";
+    homepage = "https://github.com/dmerejkowsky/dfmt";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ cole-h ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/diction/default.nix b/nixpkgs/pkgs/tools/text/diction/default.nix
new file mode 100644
index 000000000000..be486cccf549
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/diction/default.nix
@@ -0,0 +1,23 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "diction";
+  version = "1.13";
+
+  src = fetchurl {
+    url = "http://www.moria.de/~michael/diction/${pname}-${version}.tar.gz";
+    sha256 = "08fi971b8qa4xycxbgb42i6b5ms3qx9zpp5hwpbxy2vypfs0wph9";
+  };
+
+  meta = {
+    description = "GNU style and diction utilities";
+    longDescription = ''
+      Diction and style are two old standard Unix commands. Diction identifies
+      wordy and commonly misused phrases. Style analyses surface
+      characteristics of a document, including sentence length and other
+      readability measures.
+    '';
+    license = lib.licenses.gpl3Plus;
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/diffr/default.nix b/nixpkgs/pkgs/tools/text/diffr/default.nix
new file mode 100644
index 000000000000..a77a5dc081e8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/diffr/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, Security }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "diffr";
+  version = "v0.1.4";
+
+  src = fetchFromGitHub {
+    owner = "mookid";
+    repo = pname;
+    rev = version;
+    sha256 = "18ks5g4bx6iz9hdjxmi6a41ncxpb1hnsscdlddp2gr40k3vgd0pa";
+  };
+
+  cargoSha256 = "05rfjangmyvmqm0bvl4bcvc7m4zhg66gknh85sxr3bzrlwzacwgw";
+
+  buildInputs = (lib.optional stdenv.isDarwin Security);
+
+  preCheck = ''
+    export DIFFR_TESTS_BINARY_PATH=$releaseDir/diffr
+  '';
+
+  meta = with lib; {
+    description = "Yet another diff highlighting tool";
+    homepage = "https://github.com/mookid/diffr";
+    license = with licenses; [ mit ];
+    maintainers = with maintainers; [ davidtwco ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/diffstat/default.nix b/nixpkgs/pkgs/tools/text/diffstat/default.nix
new file mode 100644
index 000000000000..3e156cf3132d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/diffstat/default.nix
@@ -0,0 +1,27 @@
+{ fetchurl, lib, stdenv }:
+
+stdenv.mkDerivation rec {
+  pname = "diffstat";
+  version = "1.64";
+
+  src = fetchurl {
+    urls = [
+      "ftp://ftp.invisible-island.net/diffstat/diffstat-${version}.tgz"
+      "https://invisible-mirror.net/archives/diffstat/diffstat-${version}.tgz"
+    ];
+    sha256 = "sha256-uK7jjZ0uHQWSbmtVgQqdLC3UB/JNaiZzh1Y6RDbj9/w=";
+  };
+
+  meta = with lib; {
+    description = "Read output of diff and display a histogram of the changes";
+    longDescription = ''
+      diffstat reads the output of diff and displays a histogram of the
+      insertions, deletions, and modifications per-file. It is useful for
+      reviewing large, complex patch files.
+    '';
+    homepage = "https://invisible-island.net/diffstat/";
+    license = licenses.mit;
+    platforms = platforms.unix;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/difftastic/default.nix b/nixpkgs/pkgs/tools/text/difftastic/default.nix
new file mode 100644
index 000000000000..06bd7d0376b2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/difftastic/default.nix
@@ -0,0 +1,34 @@
+{ lib, fetchFromGitHub, rustPlatform, tree-sitter }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "difftastic";
+  version = "0.9";
+
+  src = fetchFromGitHub {
+    owner = "wilfred";
+    repo = pname;
+    rev = version;
+    sha256 = "sha256-spncRJjROytGnIig6ujqHu0e/XBTN4dsJ3og4aIu+l8=";
+  };
+
+  cargoSha256 = "sha256-2xGwS4wjLQ7zmfZ2gMdlUAkjPDF6SmUaiX2j1KYy0vo=";
+
+  postPatch = ''
+    pushd vendor
+    for grammar in */; do
+      if [ -d "${tree-sitter.grammars}/$grammar" ]; then
+        rm -r "$grammar"
+        ln -s "${tree-sitter.grammars}/$grammar"
+      fi
+    done
+    popd
+  '';
+
+  meta = with lib; {
+    description = "A syntax-aware diff";
+    homepage = "https://github.com/Wilfred/difftastic";
+    changelog = "https://github.com/Wilfred/difftastic/raw/${version}/CHANGELOG.md";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ethancedwards8 figsoda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/diffutils/default.nix b/nixpkgs/pkgs/tools/text/diffutils/default.nix
new file mode 100644
index 000000000000..d5f27747cf1c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/diffutils/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchurl, xz, coreutils ? null }:
+
+# Note: this package is used for bootstrapping fetchurl, and thus
+# cannot use fetchpatch! All mutable patches (generated by GitHub or
+# cgit) that are needed here should be included directly in Nixpkgs as
+# files.
+
+stdenv.mkDerivation rec {
+  pname = "diffutils";
+  version = "3.8";
+
+  src = fetchurl {
+    url = "mirror://gnu/diffutils/diffutils-${version}.tar.xz";
+    sha256 = "sha256-pr3X0bMSZtEcT03mwbdI1GB6sCMa9RiPwlM9CuJDj+w=";
+  };
+
+  outputs = [ "out" "info" ];
+
+  nativeBuildInputs = [ xz.bin ];
+  /* If no explicit coreutils is given, use the one from stdenv. */
+  buildInputs = [ coreutils ];
+
+  configureFlags =
+    # "pr" need not be on the PATH as a run-time dep, so we need to tell
+    # configure where it is. Covers the cross and native case alike.
+    lib.optional (coreutils != null) "PR_PROGRAM=${coreutils}/bin/pr"
+    ++ lib.optional (stdenv.buildPlatform != stdenv.hostPlatform) "gl_cv_func_getopt_gnu=yes";
+
+  meta = with lib; {
+    homepage = "https://www.gnu.org/software/diffutils/diffutils.html";
+    description = "Commands for showing the differences between files (diff, cmp, etc.)";
+    license = licenses.gpl3;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/dirdiff/default.nix b/nixpkgs/pkgs/tools/text/dirdiff/default.nix
new file mode 100644
index 000000000000..b49df59b29e1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dirdiff/default.nix
@@ -0,0 +1,59 @@
+{ copyDesktopItems, fetchurl, lib, makeDesktopItem, stdenv, tcl, tk }:
+
+stdenv.mkDerivation rec {
+  pname = "dirdiff";
+  version = "2.1";
+
+  src = fetchurl {
+    url = "https://www.samba.org/ftp/paulus/${pname}-${version}.tar.gz";
+    sha256 = "0lljd8av68j70733yshzzhxjr1lm0vgmbqsm8f02g03qsma3cdyb";
+  };
+
+  nativeBuildInputs = [ copyDesktopItems ];
+  buildInputs = [ tcl tk ];
+
+  # Some light path patching.
+  patches = [ ./dirdiff-2.1-vars.patch ];
+  postPatch = ''
+    for file in dirdiff Makefile; do
+      substituteInPlace "$file" \
+          --subst-var out \
+          --subst-var-by tcl ${tcl} \
+          --subst-var-by tk ${tk}
+    done
+  '';
+
+  # If we don't create the directories ourselves, then 'make install' creates
+  # files named 'bin' and 'lib'.
+  preInstall = ''
+    mkdir -p $out/bin $out/lib
+  '';
+
+  installFlags = [
+    "BINDIR=${placeholder "out"}/bin"
+    "LIBDIR=${placeholder "out"}/lib"
+  ];
+
+  desktopItems = [
+    (makeDesktopItem {
+      name = "dirdiff";
+      exec = "dirdiff";
+      desktopName = "Dirdiff";
+      genericName = "Directory Diff Viewer";
+      comment = "Diff and merge directory trees";
+      categories = "Development;";
+    })
+  ];
+
+  meta = with lib; {
+    description = "Graphical directory tree diff and merge tool";
+    longDescription = ''
+      Dirdiff is a graphical tool for displaying the differences between
+      directory trees and for merging changes from one tree into another.
+    '';
+    homepage = "https://www.samba.org/ftp/paulus/";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ khumba ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/dirdiff/dirdiff-2.1-vars.patch b/nixpkgs/pkgs/tools/text/dirdiff/dirdiff-2.1-vars.patch
new file mode 100644
index 000000000000..4e7aa025754a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dirdiff/dirdiff-2.1-vars.patch
@@ -0,0 +1,32 @@
+diff '--color=auto' -ru dirdiff-2.1/dirdiff dirdiff-2.1-patched/dirdiff
+--- dirdiff-2.1/dirdiff	2005-04-20 03:09:53.000000000 -0700
++++ dirdiff-2.1-patched/dirdiff	2021-02-14 22:54:09.837692023 -0800
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ # Tcl ignores the next line \
+-exec wish "$0" -- "${1+$@}"
++exec @tk@/bin/wish "$0" -- "${1+$@}"
+ 
+ # Copyright (C) 1999-2004 Paul Mackerras.  All rights reserved.
+ # This program is free software; it may be used, copied, modified
+@@ -17,7 +17,7 @@
+ set TclExe [info nameofexecutable]
+ set compound_ok [expr {$tcl_version >= 8.4}]
+ 
+-set nofilecmp [catch {load libfilecmp.so.0.0}]
++set nofilecmp [catch {load @out@/lib/libfilecmp.so.0.0}]
+ set rcsflag {}
+ set diffbflag {}
+ set diffBflag {}
+diff '--color=auto' -ru dirdiff-2.1/Makefile dirdiff-2.1-patched/Makefile
+--- dirdiff-2.1/Makefile	2005-04-19 03:22:01.000000000 -0700
++++ dirdiff-2.1-patched/Makefile	2021-02-14 22:54:58.575400923 -0800
+@@ -7,7 +7,7 @@
+ INSTALL=install
+ 
+ # You may need to change the -I arguments depending on your system
+-CFLAGS=-O3 -I/usr/include/tcl8.3/ -I/usr/include/tcl
++CFLAGS=-O3 -I@tcl@/include
+ 
+ all:	libfilecmp.so.0.0
+ 
diff --git a/nixpkgs/pkgs/tools/text/discount/default.nix b/nixpkgs/pkgs/tools/text/discount/default.nix
new file mode 100644
index 000000000000..264e944028e3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/discount/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchFromGitHub }:
+
+stdenv.mkDerivation rec {
+  version = "2.2.7";
+  pname = "discount";
+
+  src = fetchFromGitHub {
+    owner = "Orc";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "0p2gznrsvv82zxbajqir8y2ap1ribbgagqg1bzhv3i81p2byhjh7";
+  };
+
+  patches = ./fix-configure-path.patch;
+  configureScript = "./configure.sh";
+
+  configureFlags = [
+    "--enable-all-features"
+    "--pkg-config"
+    "--shared"
+    "--with-fenced-code"
+  ];
+
+  doCheck = true;
+
+  meta = with lib; {
+    description = "Implementation of Markdown markup language in C";
+    homepage = "http://www.pell.portland.or.us/~orc/Code/discount/";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ shell ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/discount/fix-configure-path.patch b/nixpkgs/pkgs/tools/text/discount/fix-configure-path.patch
new file mode 100644
index 000000000000..045b369b4b69
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/discount/fix-configure-path.patch
@@ -0,0 +1,12 @@
+diff -rupN discount-2.1.6-original/configure.inc discount-2.1.6/configure.inc
+--- discount-2.1.6-original/configure.inc	2014-10-10 15:34:24.158325345 +0100
++++ discount-2.1.6/configure.inc	2014-10-10 15:34:33.553325321 +0100
+@@ -32,7 +32,7 @@
+ # this preamble code is executed when this file is sourced and it picks
+ # interesting things off the command line.
+ #
+-ac_default_path="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin"
++ac_default_path=$PATH
+ 
+ ac_standard="--src=DIR		where the source lives (.)
+ --prefix=DIR		where to install the final product (/usr/local)
diff --git a/nixpkgs/pkgs/tools/text/dos2unix/default.nix b/nixpkgs/pkgs/tools/text/dos2unix/default.nix
new file mode 100644
index 000000000000..f694b91762c5
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/dos2unix/default.nix
@@ -0,0 +1,23 @@
+{lib, stdenv, fetchurl, perl, gettext }:
+
+stdenv.mkDerivation rec {
+  pname = "dos2unix";
+  version = "7.4.2";
+
+  src = fetchurl {
+    url = "https://waterlan.home.xs4all.nl/dos2unix/${pname}-${version}.tar.gz";
+    sha256 = "00dfsf4rfyjb5j12gan8xjiirm0asshdz6dmd3l34a7ays6wadb0";
+  };
+
+  nativeBuildInputs = [ perl gettext ];
+  makeFlags = [ "prefix=${placeholder "out"}" ];
+
+  meta = with lib; {
+    description = "Convert text files with DOS or Mac line breaks to Unix line breaks and vice versa";
+    homepage = "https://waterlan.home.xs4all.nl/dos2unix.html";
+    changelog = "https://sourceforge.net/p/dos2unix/dos2unix/ci/dos2unix-${version}/tree/dos2unix/NEWS.txt?format=raw";
+    license = licenses.bsd2;
+    maintainers = with maintainers; [ c0bw3b ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/each/default.nix b/nixpkgs/pkgs/tools/text/each/default.nix
new file mode 100644
index 000000000000..0218cf5dde27
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/each/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, fetchFromGitHub
+, rustPlatform
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "each";
+  version = "0.1.3";
+
+  src = fetchFromGitHub {
+    owner = "arraypad";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "04rx8jf871l4darfx6029dhpnbpmzwjgzazayp1qcaadsk8207z5";
+  };
+
+  cargoSha256 = "1r7nzfh7v2mlp0wdrcpqfj68h3zmip2m3d4z2nwxyikmw7c80car";
+
+  meta = with lib; {
+    description = " A better way of working with structured data on the command line";
+    homepage = "https://github.com/arraypad/each";
+    license = with licenses; [ mit ];
+    maintainers = with maintainers; [ thiagokokada ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ebook-tools/default.nix b/nixpkgs/pkgs/tools/text/ebook-tools/default.nix
new file mode 100644
index 000000000000..1a46110e2a42
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ebook-tools/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchurl, cmake, pkg-config, libxml2, libzip }:
+
+stdenv.mkDerivation rec {
+  pname = "ebook-tools";
+  version = "0.2.2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/ebook-tools/ebook-tools-${version}.tar.gz";
+    sha256 = "1bi7wsz3p5slb43kj7lgb3r6lb91lvb6ldi556k4y50ix6b5khyb";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+  buildInputs = [ libxml2 libzip ];
+
+  preConfigure =
+    ''
+      NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE $(pkg-config --cflags libzip)"
+    '';
+
+  meta = with lib; {
+    homepage = "http://ebook-tools.sourceforge.net";
+    description = "Tools and library for dealing with various ebook file formats";
+    maintainers = [ ];
+    platforms = platforms.all;
+    license = licenses.mit;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/enca/default.nix b/nixpkgs/pkgs/tools/text/enca/default.nix
new file mode 100644
index 000000000000..7015bd4453cb
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/enca/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, libiconv, recode }:
+
+stdenv.mkDerivation rec {
+  pname = "enca";
+  version = "1.19";
+
+  src = fetchurl {
+    url = "https://dl.cihar.com/enca/${pname}-${version}.tar.xz";
+    sha256 = "1f78jmrggv3jymql8imm5m9yc8nqjw5l99mpwki2245l8357wj1s";
+  };
+
+  buildInputs = [ recode libiconv ];
+
+  meta = with lib; {
+    description = "Detects the encoding of text files and reencodes them";
+
+    longDescription = ''
+        Enca detects the encoding of text files, on the basis of knowledge
+        of their language. It can also convert them to other encodings,
+        allowing you to recode files without knowing their current encoding.
+        It supports most of Central and East European languages, and a few
+        Unicode variants, independently on language.
+    '';
+
+    license = licenses.gpl2;
+
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/enscript/default.nix b/nixpkgs/pkgs/tools/text/enscript/default.nix
new file mode 100644
index 000000000000..1299ef78679c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/enscript/default.nix
@@ -0,0 +1,44 @@
+{ lib, stdenv, fetchurl, gettext }:
+
+stdenv.mkDerivation rec {
+  pname = "enscript";
+  version = "1.6.6";
+
+  src = fetchurl {
+    url = "mirror://gnu/enscript/enscript-${version}.tar.gz";
+    sha256 = "1fy0ymvzrrvs889zanxcaxjfcxarm2d3k43c9frmbl1ld7dblmkd";
+  };
+
+  preBuild =
+    ''
+      # Fix building on Darwin with GCC.
+      substituteInPlace compat/regex.c --replace \
+         __private_extern__  '__attribute__ ((visibility ("hidden")))'
+    '';
+
+  buildInputs = [ gettext ];
+
+  doCheck = true;
+
+  meta = {
+    description = "Converter from ASCII to PostScript, HTML, or RTF";
+
+    longDescription =
+      '' GNU Enscript converts ASCII files to PostScript, HTML, or RTF and
+         stores generated output to a file or sends it directly to the
+         printer.  It includes features for `pretty-printing'
+         (language-sensitive code highlighting) in several programming
+         languages.
+
+         Enscript can be easily extended to handle different output media and
+         it has many options that can be used to customize printouts.
+      '';
+
+    license = lib.licenses.gpl3Plus;
+
+    homepage = "https://www.gnu.org/software/enscript/";
+
+    maintainers = [ ];
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/epubcheck/default.nix b/nixpkgs/pkgs/tools/text/epubcheck/default.nix
new file mode 100644
index 000000000000..45196422ff54
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/epubcheck/default.nix
@@ -0,0 +1,41 @@
+{ lib, stdenv, fetchzip
+, jre, makeWrapper }:
+
+stdenv.mkDerivation rec {
+  pname = "epubcheck";
+  version = "4.2.6";
+
+  src = fetchzip {
+    url = "https://github.com/w3c/epubcheck/releases/download/v${version}/epubcheck-${version}.zip";
+    sha256 = "sha256-f4r0ODKvZrl+YBcP2T9Z+zEuCyvQm9W7GNiLTr4p278=";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/lib
+    cp -r lib/* $out/lib
+
+    mkdir -p $out/libexec/epubcheck
+    cp epubcheck.jar $out/libexec/epubcheck
+
+    classpath=$out/libexec/epubcheck/epubcheck.jar
+    for jar in $out/lib/*.jar; do
+      classpath="$classpath:$jar"
+    done
+
+    mkdir -p $out/bin
+    makeWrapper ${jre}/bin/java $out/bin/epubcheck \
+      --add-flags "-classpath $classpath com.adobe.epubcheck.tool.Checker"
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/w3c/epubcheck";
+    description = "Validation tool for EPUB";
+    license = with licenses; [ asl20 bsd3 mpl10 w3c ];
+    platforms = platforms.all;
+    maintainers = with maintainers; [ eadwu ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/esh/default.nix b/nixpkgs/pkgs/tools/text/esh/default.nix
new file mode 100644
index 000000000000..a1d6db2a7c2d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/esh/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, fetchFromGitHub, asciidoctor, gawk, gnused, runtimeShell }:
+
+stdenv.mkDerivation rec {
+  pname = "esh";
+  version = "0.1.1";
+
+  src = fetchFromGitHub {
+    owner = "jirutka";
+    repo = "esh";
+    rev = "v${version}";
+    sha256 = "1ddaji5nplf1dyvgkrhqjy8m5djaycqcfhjv30yprj1avjymlj6w";
+  };
+
+  nativeBuildInputs = [ asciidoctor ];
+
+  buildInputs = [ gawk gnused ];
+
+  makeFlags = [ "prefix=$(out)" "DESTDIR=" ];
+
+  postPatch = ''
+    patchShebangs .
+    substituteInPlace esh \
+        --replace '"/bin/sh"' '"${runtimeShell}"' \
+        --replace '"awk"' '"${gawk}/bin/awk"' \
+        --replace 'sed' '${gnused}/bin/sed'
+    substituteInPlace tests/test-dump.exp \
+        --replace '#!/bin/sh' '#!${runtimeShell}'
+  '';
+
+  doCheck = true;
+  checkTarget = "test";
+
+  meta = with lib; {
+    description = "Simple templating engine based on shell";
+    homepage = "https://github.com/jirutka/esh";
+    license = licenses.mit;
+    maintainers = with maintainers; [ mnacamura ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/fanficfare/default.nix b/nixpkgs/pkgs/tools/text/fanficfare/default.nix
new file mode 100644
index 000000000000..5fb70f63dc31
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/fanficfare/default.nix
@@ -0,0 +1,28 @@
+{ lib, python3Packages }:
+
+python3Packages.buildPythonApplication rec {
+  pname = "FanFicFare";
+  version = "3.21.0";
+
+  src = python3Packages.fetchPypi {
+    inherit pname version;
+    sha256 = "16hklfbww6ibmjr32gg98nlnzl4dwanz6lm3fzg2x3vd7d54m92c";
+  };
+
+  propagatedBuildInputs = with python3Packages; [
+    beautifulsoup4
+    chardet
+    html5lib
+    html2text
+  ];
+
+  doCheck = false; # no tests exist
+
+  meta = with lib; {
+    description = "Tool for making eBooks from fanfiction web sites";
+    homepage = "https://github.com/JimmXinu/FanFicFare";
+    license = licenses.gpl3;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ dwarfmaster ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/fastmod/default.nix b/nixpkgs/pkgs/tools/text/fastmod/default.nix
new file mode 100644
index 000000000000..d6e2dc4dd1fc
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/fastmod/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv
+, fetchFromGitHub
+, rustPlatform
+, libiconv
+, Security
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "fastmod";
+  version = "0.4.2";
+
+  src = fetchFromGitHub {
+    owner = "facebookincubator";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-Lv8hARD/aVWiWpJQmPWPeACpX15+3NogoUl5yh63E7A=";
+  };
+
+  cargoSha256 = "sha256-L1MKoVacVKcpEG2IfS+eENxFZNiSaTDTxfFbFlvzYl8=";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ libiconv Security ];
+
+  meta = with lib; {
+    description = "A utility that makes sweeping changes to large, shared code bases";
+    homepage = "https://github.com/facebookincubator/fastmod";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ jduan ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/frangipanni/default.nix b/nixpkgs/pkgs/tools/text/frangipanni/default.nix
new file mode 100644
index 000000000000..58da1a4be4df
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/frangipanni/default.nix
@@ -0,0 +1,22 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "frangipanni";
+  version = "0.5.0";
+
+  src = fetchFromGitHub {
+    owner = "birchb1024";
+    repo = "frangipanni";
+    rev = "v${version}";
+    sha256 = "sha256-jIXyqwZWfCBSDTTodHTct4V5rjYv7h4Vcw7cXOFk17w=";
+  };
+
+  vendorSha256 = "sha256-TSN5M/UCTtfoTf1hDCfrJMCFdSwL/NVXssgt4aefom8=";
+
+  meta = with lib; {
+    description = "Convert lines of text into a tree structure";
+    homepage = "https://github.com/birchb1024/frangipanni";
+    license = licenses.mit;
+    maintainers = with maintainers; [ siraben ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/fst/0001-cargo-lockfile.patch b/nixpkgs/pkgs/tools/text/fst/0001-cargo-lockfile.patch
new file mode 100644
index 000000000000..eb5ec5748553
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/fst/0001-cargo-lockfile.patch
@@ -0,0 +1,900 @@
+From 99bfed6f7278ae9b5edfc42644e57eb0ae7669e1 Mon Sep 17 00:00:00 2001
+From: "Robert T. McGibbon" <rmcgibbo@gmail.com>
+Date: Wed, 22 Sep 2021 16:00:13 -0400
+Subject: [PATCH 1/1] Create cargo lock file for 0.4.7
+
+---
+ Cargo.lock | 881 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 881 insertions(+)
+ create mode 100644 Cargo.lock
+
+diff --git a/Cargo.lock b/Cargo.lock
+new file mode 100644
+index 0000000..37e9c5f
+--- /dev/null
++++ b/Cargo.lock
+@@ -0,0 +1,881 @@
++# This file is automatically @generated by Cargo.
++# It is not intended for manual editing.
++[[package]]
++name = "anyhow"
++version = "1.0.44"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
++
++[[package]]
++name = "atty"
++version = "0.2.14"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
++dependencies = [
++ "hermit-abi",
++ "libc",
++ "winapi",
++]
++
++[[package]]
++name = "autocfg"
++version = "1.0.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
++
++[[package]]
++name = "bit-set"
++version = "0.5.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
++dependencies = [
++ "bit-vec",
++]
++
++[[package]]
++name = "bit-vec"
++version = "0.6.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
++
++[[package]]
++name = "bitflags"
++version = "1.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
++
++[[package]]
++name = "bstr"
++version = "0.2.17"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
++dependencies = [
++ "lazy_static",
++ "memchr",
++ "regex-automata",
++ "serde",
++]
++
++[[package]]
++name = "bumpalo"
++version = "3.7.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
++
++[[package]]
++name = "cast"
++version = "0.2.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
++dependencies = [
++ "rustc_version",
++]
++
++[[package]]
++name = "cfg-if"
++version = "0.1.10"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
++
++[[package]]
++name = "cfg-if"
++version = "1.0.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
++
++[[package]]
++name = "clap"
++version = "2.33.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
++dependencies = [
++ "bitflags",
++ "textwrap",
++ "unicode-width",
++]
++
++[[package]]
++name = "criterion"
++version = "0.3.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
++dependencies = [
++ "atty",
++ "cast",
++ "clap",
++ "criterion-plot",
++ "csv",
++ "itertools",
++ "lazy_static",
++ "num-traits",
++ "oorandom",
++ "plotters",
++ "rayon",
++ "regex",
++ "serde",
++ "serde_cbor",
++ "serde_derive",
++ "serde_json",
++ "tinytemplate",
++ "walkdir",
++]
++
++[[package]]
++name = "criterion-plot"
++version = "0.4.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
++dependencies = [
++ "cast",
++ "itertools",
++]
++
++[[package]]
++name = "crossbeam-channel"
++version = "0.4.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
++dependencies = [
++ "crossbeam-utils 0.7.2",
++ "maybe-uninit",
++]
++
++[[package]]
++name = "crossbeam-channel"
++version = "0.5.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
++dependencies = [
++ "cfg-if 1.0.0",
++ "crossbeam-utils 0.8.5",
++]
++
++[[package]]
++name = "crossbeam-deque"
++version = "0.8.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
++dependencies = [
++ "cfg-if 1.0.0",
++ "crossbeam-epoch",
++ "crossbeam-utils 0.8.5",
++]
++
++[[package]]
++name = "crossbeam-epoch"
++version = "0.9.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
++dependencies = [
++ "cfg-if 1.0.0",
++ "crossbeam-utils 0.8.5",
++ "lazy_static",
++ "memoffset",
++ "scopeguard",
++]
++
++[[package]]
++name = "crossbeam-utils"
++version = "0.7.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
++dependencies = [
++ "autocfg",
++ "cfg-if 0.1.10",
++ "lazy_static",
++]
++
++[[package]]
++name = "crossbeam-utils"
++version = "0.8.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
++dependencies = [
++ "cfg-if 1.0.0",
++ "lazy_static",
++]
++
++[[package]]
++name = "csv"
++version = "1.1.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
++dependencies = [
++ "bstr",
++ "csv-core",
++ "itoa",
++ "ryu",
++ "serde",
++]
++
++[[package]]
++name = "csv-core"
++version = "0.1.10"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
++dependencies = [
++ "memchr",
++]
++
++[[package]]
++name = "doc-comment"
++version = "0.3.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
++
++[[package]]
++name = "either"
++version = "1.6.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
++
++[[package]]
++name = "fnv"
++version = "1.0.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
++
++[[package]]
++name = "fst"
++version = "0.4.7"
++dependencies = [
++ "doc-comment",
++ "fnv",
++ "memmap",
++ "quickcheck",
++ "rand 0.7.3",
++ "utf8-ranges",
++]
++
++[[package]]
++name = "fst-bench"
++version = "0.0.1"
++dependencies = [
++ "criterion",
++ "fnv",
++ "fst",
++]
++
++[[package]]
++name = "fst-bin"
++version = "0.4.1"
++dependencies = [
++ "anyhow",
++ "bit-set",
++ "bstr",
++ "clap",
++ "crossbeam-channel 0.4.4",
++ "csv",
++ "fst",
++ "memmap",
++ "num_cpus",
++ "regex-automata",
++ "serde",
++ "tempfile",
++]
++
++[[package]]
++name = "getrandom"
++version = "0.1.16"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
++dependencies = [
++ "cfg-if 1.0.0",
++ "libc",
++ "wasi 0.9.0+wasi-snapshot-preview1",
++]
++
++[[package]]
++name = "getrandom"
++version = "0.2.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
++dependencies = [
++ "cfg-if 1.0.0",
++ "libc",
++ "wasi 0.10.2+wasi-snapshot-preview1",
++]
++
++[[package]]
++name = "half"
++version = "1.7.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
++
++[[package]]
++name = "hermit-abi"
++version = "0.1.19"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
++dependencies = [
++ "libc",
++]
++
++[[package]]
++name = "itertools"
++version = "0.10.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
++dependencies = [
++ "either",
++]
++
++[[package]]
++name = "itoa"
++version = "0.4.8"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
++
++[[package]]
++name = "js-sys"
++version = "0.3.55"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
++dependencies = [
++ "wasm-bindgen",
++]
++
++[[package]]
++name = "lazy_static"
++version = "1.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
++
++[[package]]
++name = "libc"
++version = "0.2.102"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
++
++[[package]]
++name = "log"
++version = "0.4.14"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
++dependencies = [
++ "cfg-if 1.0.0",
++]
++
++[[package]]
++name = "maybe-uninit"
++version = "2.0.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
++
++[[package]]
++name = "memchr"
++version = "2.4.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
++
++[[package]]
++name = "memmap"
++version = "0.7.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
++dependencies = [
++ "libc",
++ "winapi",
++]
++
++[[package]]
++name = "memoffset"
++version = "0.6.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
++dependencies = [
++ "autocfg",
++]
++
++[[package]]
++name = "num-traits"
++version = "0.2.14"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
++dependencies = [
++ "autocfg",
++]
++
++[[package]]
++name = "num_cpus"
++version = "1.13.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
++dependencies = [
++ "hermit-abi",
++ "libc",
++]
++
++[[package]]
++name = "oorandom"
++version = "11.1.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
++
++[[package]]
++name = "plotters"
++version = "0.3.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
++dependencies = [
++ "num-traits",
++ "plotters-backend",
++ "plotters-svg",
++ "wasm-bindgen",
++ "web-sys",
++]
++
++[[package]]
++name = "plotters-backend"
++version = "0.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
++
++[[package]]
++name = "plotters-svg"
++version = "0.3.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
++dependencies = [
++ "plotters-backend",
++]
++
++[[package]]
++name = "ppv-lite86"
++version = "0.2.10"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
++
++[[package]]
++name = "proc-macro2"
++version = "1.0.29"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
++dependencies = [
++ "unicode-xid",
++]
++
++[[package]]
++name = "quickcheck"
++version = "0.9.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
++dependencies = [
++ "rand 0.7.3",
++ "rand_core 0.5.1",
++]
++
++[[package]]
++name = "quote"
++version = "1.0.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
++dependencies = [
++ "proc-macro2",
++]
++
++[[package]]
++name = "rand"
++version = "0.7.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
++dependencies = [
++ "getrandom 0.1.16",
++ "libc",
++ "rand_chacha 0.2.2",
++ "rand_core 0.5.1",
++ "rand_hc 0.2.0",
++]
++
++[[package]]
++name = "rand"
++version = "0.8.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
++dependencies = [
++ "libc",
++ "rand_chacha 0.3.1",
++ "rand_core 0.6.3",
++ "rand_hc 0.3.1",
++]
++
++[[package]]
++name = "rand_chacha"
++version = "0.2.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
++dependencies = [
++ "ppv-lite86",
++ "rand_core 0.5.1",
++]
++
++[[package]]
++name = "rand_chacha"
++version = "0.3.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
++dependencies = [
++ "ppv-lite86",
++ "rand_core 0.6.3",
++]
++
++[[package]]
++name = "rand_core"
++version = "0.5.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
++dependencies = [
++ "getrandom 0.1.16",
++]
++
++[[package]]
++name = "rand_core"
++version = "0.6.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
++dependencies = [
++ "getrandom 0.2.3",
++]
++
++[[package]]
++name = "rand_hc"
++version = "0.2.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
++dependencies = [
++ "rand_core 0.5.1",
++]
++
++[[package]]
++name = "rand_hc"
++version = "0.3.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
++dependencies = [
++ "rand_core 0.6.3",
++]
++
++[[package]]
++name = "rayon"
++version = "1.5.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
++dependencies = [
++ "autocfg",
++ "crossbeam-deque",
++ "either",
++ "rayon-core",
++]
++
++[[package]]
++name = "rayon-core"
++version = "1.9.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
++dependencies = [
++ "crossbeam-channel 0.5.1",
++ "crossbeam-deque",
++ "crossbeam-utils 0.8.5",
++ "lazy_static",
++ "num_cpus",
++]
++
++[[package]]
++name = "redox_syscall"
++version = "0.2.10"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
++dependencies = [
++ "bitflags",
++]
++
++[[package]]
++name = "regex"
++version = "1.5.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
++dependencies = [
++ "regex-syntax",
++]
++
++[[package]]
++name = "regex-automata"
++version = "0.1.10"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
++dependencies = [
++ "fst",
++ "regex-syntax",
++]
++
++[[package]]
++name = "regex-syntax"
++version = "0.6.25"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
++
++[[package]]
++name = "remove_dir_all"
++version = "0.5.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
++dependencies = [
++ "winapi",
++]
++
++[[package]]
++name = "rustc_version"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
++dependencies = [
++ "semver",
++]
++
++[[package]]
++name = "ryu"
++version = "1.0.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
++
++[[package]]
++name = "same-file"
++version = "1.0.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
++dependencies = [
++ "winapi-util",
++]
++
++[[package]]
++name = "scopeguard"
++version = "1.1.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
++
++[[package]]
++name = "semver"
++version = "1.0.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
++
++[[package]]
++name = "serde"
++version = "1.0.130"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
++dependencies = [
++ "serde_derive",
++]
++
++[[package]]
++name = "serde_cbor"
++version = "0.11.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
++dependencies = [
++ "half",
++ "serde",
++]
++
++[[package]]
++name = "serde_derive"
++version = "1.0.130"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "syn",
++]
++
++[[package]]
++name = "serde_json"
++version = "1.0.68"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
++dependencies = [
++ "itoa",
++ "ryu",
++ "serde",
++]
++
++[[package]]
++name = "syn"
++version = "1.0.76"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "unicode-xid",
++]
++
++[[package]]
++name = "tempfile"
++version = "3.2.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
++dependencies = [
++ "cfg-if 1.0.0",
++ "libc",
++ "rand 0.8.4",
++ "redox_syscall",
++ "remove_dir_all",
++ "winapi",
++]
++
++[[package]]
++name = "textwrap"
++version = "0.11.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
++dependencies = [
++ "unicode-width",
++]
++
++[[package]]
++name = "tinytemplate"
++version = "1.2.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
++dependencies = [
++ "serde",
++ "serde_json",
++]
++
++[[package]]
++name = "unicode-width"
++version = "0.1.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
++
++[[package]]
++name = "unicode-xid"
++version = "0.2.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
++
++[[package]]
++name = "utf8-ranges"
++version = "1.0.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
++
++[[package]]
++name = "walkdir"
++version = "2.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
++dependencies = [
++ "same-file",
++ "winapi",
++ "winapi-util",
++]
++
++[[package]]
++name = "wasi"
++version = "0.9.0+wasi-snapshot-preview1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
++
++[[package]]
++name = "wasi"
++version = "0.10.2+wasi-snapshot-preview1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
++
++[[package]]
++name = "wasm-bindgen"
++version = "0.2.78"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
++dependencies = [
++ "cfg-if 1.0.0",
++ "wasm-bindgen-macro",
++]
++
++[[package]]
++name = "wasm-bindgen-backend"
++version = "0.2.78"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
++dependencies = [
++ "bumpalo",
++ "lazy_static",
++ "log",
++ "proc-macro2",
++ "quote",
++ "syn",
++ "wasm-bindgen-shared",
++]
++
++[[package]]
++name = "wasm-bindgen-macro"
++version = "0.2.78"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
++dependencies = [
++ "quote",
++ "wasm-bindgen-macro-support",
++]
++
++[[package]]
++name = "wasm-bindgen-macro-support"
++version = "0.2.78"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "syn",
++ "wasm-bindgen-backend",
++ "wasm-bindgen-shared",
++]
++
++[[package]]
++name = "wasm-bindgen-shared"
++version = "0.2.78"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
++
++[[package]]
++name = "web-sys"
++version = "0.3.55"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
++dependencies = [
++ "js-sys",
++ "wasm-bindgen",
++]
++
++[[package]]
++name = "winapi"
++version = "0.3.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
++dependencies = [
++ "winapi-i686-pc-windows-gnu",
++ "winapi-x86_64-pc-windows-gnu",
++]
++
++[[package]]
++name = "winapi-i686-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
++
++[[package]]
++name = "winapi-util"
++version = "0.1.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
++dependencies = [
++ "winapi",
++]
++
++[[package]]
++name = "winapi-x86_64-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+-- 
+2.29.3
+
diff --git a/nixpkgs/pkgs/tools/text/fst/default.nix b/nixpkgs/pkgs/tools/text/fst/default.nix
new file mode 100644
index 000000000000..1e3759c6a578
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/fst/default.nix
@@ -0,0 +1,45 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, rustPlatform
+, libiconv
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "fst";
+  version = "0.4.7";
+
+  src = fetchFromGitHub {
+    owner = "BurntSushi";
+    repo = pname;
+    rev = version;
+    sha256 = "sha256-fXbX6idoGBtQiKM37C0z89OH/5H2PkZdwYLksXbbakE=";
+  };
+
+  cargoPatches = [
+    # Add Cargo.lock lockfile, which upstream does not include
+    ./0001-cargo-lockfile.patch
+  ];
+
+  cargoBuildFlags = [ "--workspace" ];
+  cargoSha256 = "sha256-2gy4i4CwZP6LB5ea1LBSfeAV6bNnsvDbxw0Unur0Hm4=";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
+
+  doInstallCheck = true;
+  installCheckPhase = ''
+    csv="$(mktemp)"
+    fst="$(mktemp)"
+    printf "abc,1\nabcd,1" > "$csv"
+    $out/bin/fst map "$csv" "$fst" --force
+    $out/bin/fst fuzzy "$fst" 'abc'
+    $out/bin/fst --help > /dev/null
+  '';
+
+  meta = with lib; {
+    description = "Represent large sets and maps compactly with finite state transducers";
+    homepage = "https://github.com/BurntSushi/fst";
+    license = with licenses; [ unlicense /* or */ mit ];
+    maintainers = with maintainers; [ rmcgibbo ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gawk/default.nix b/nixpkgs/pkgs/tools/text/gawk/default.nix
new file mode 100644
index 000000000000..3eb9ed3000c2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gawk/default.nix
@@ -0,0 +1,77 @@
+{ lib, stdenv, fetchurl
+# TODO: links -lsigsegv but loses the reference for some reason
+, withSigsegv ? (false && stdenv.hostPlatform.system != "x86_64-cygwin"), libsigsegv
+, interactive ? false, readline
+
+/* Test suite broke on:
+       stdenv.isCygwin # XXX: `test-dup2' segfaults on Cygwin 6.1
+    || stdenv.isDarwin # XXX: `locale' segfaults
+    || stdenv.isSunOS  # XXX: `_backsmalls1' fails, locale stuff?
+    || stdenv.isFreeBSD
+*/
+, doCheck ? (interactive && stdenv.isLinux), glibcLocales ? null
+, locale ? null
+}:
+
+assert (doCheck && stdenv.isLinux) -> glibcLocales != null;
+
+stdenv.mkDerivation rec {
+  pname = "gawk";
+  version = "5.1.0";
+
+  src = fetchurl {
+    url = "mirror://gnu/gawk/gawk-${version}.tar.xz";
+    sha256 = "1gc2cccqy1x1bf6rhwlmd8q7dz7gnam6nwgl38bxapv6qm5flpyg";
+  };
+
+  # When we do build separate interactive version, it makes sense to always include man.
+  outputs = [ "out" "info" ]
+    ++ lib.optional (!interactive) "man";
+
+  nativeBuildInputs = lib.optional (doCheck && stdenv.isLinux) glibcLocales;
+
+  buildInputs = lib.optional withSigsegv libsigsegv
+    ++ lib.optional interactive readline
+    ++ lib.optional stdenv.isDarwin locale;
+
+  configureFlags = [
+    (if withSigsegv then "--with-libsigsegv-prefix=${libsigsegv}" else "--without-libsigsegv")
+    (if interactive then "--with-readline=${readline.dev}" else "--without-readline")
+  ];
+
+  makeFlags = [
+    "AR=${stdenv.cc.targetPrefix}ar"
+  ];
+
+  inherit doCheck;
+
+  postInstall = ''
+    rm "$out"/bin/gawk-*
+    ln -s gawk.1 "''${!outputMan}"/share/man/man1/awk.1
+  '';
+
+  passthru = {
+    libsigsegv = if withSigsegv then libsigsegv else null; # for stdenv bootstrap
+  };
+
+  meta = with lib; {
+    homepage = "https://www.gnu.org/software/gawk/";
+    description = "GNU implementation of the Awk programming language";
+    longDescription = ''
+      Many computer users need to manipulate text files: extract and then
+      operate on data from parts of certain lines while discarding the rest,
+      make changes in various text files wherever certain patterns appear,
+      and so on.  To write a program to do these things in a language such as
+      C or Pascal is a time-consuming inconvenience that may take many lines
+      of code.  The job is easy with awk, especially the GNU implementation:
+      Gawk.
+
+      The awk utility interprets a special-purpose programming language that
+      makes it possible to handle many data-reformatting jobs with just a few
+      lines of code.
+    '';
+    license = licenses.gpl3Plus;
+    platforms = platforms.unix ++ platforms.windows;
+    maintainers = [ ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gawk/gawk-with-extensions.nix b/nixpkgs/pkgs/tools/text/gawk/gawk-with-extensions.nix
new file mode 100644
index 000000000000..1b82d798d330
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gawk/gawk-with-extensions.nix
@@ -0,0 +1,13 @@
+{ runCommand, gawk, extensions, makeWrapper }:
+
+runCommand "gawk-with-extensions" {
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ gawk ] ++ extensions;
+} ''
+  mkdir -p $out/bin
+  for i in ${gawk}/bin/*; do
+    name="$(basename "$i")"
+    makeWrapper $i $out/bin/$name \
+      --prefix AWKLIBPATH : "${gawk}/lib/gawk:''${AWKLIBPATH:-}"
+  done
+''
diff --git a/nixpkgs/pkgs/tools/text/gawk/gawkextlib.nix b/nixpkgs/pkgs/tools/text/gawk/gawkextlib.nix
new file mode 100644
index 000000000000..1d3f14ea336e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gawk/gawkextlib.nix
@@ -0,0 +1,149 @@
+{ lib, stdenv, recurseIntoAttrs, fetchgit, writeText, pkg-config, autoreconfHook
+, autoconf, automake, libiconv, libtool, texinfo, gettext, gawk, rapidjson, gd
+, shapelib, libharu, lmdb, gmp, glibcLocales, mpfr, more, postgresql, hiredis
+, expat, tre, makeWrapper }:
+
+let
+  buildExtension = lib.makeOverridable
+    ({ name, gawkextlib, extraBuildInputs ? [ ], doCheck ? true }:
+      let is_extension = !isNull gawkextlib;
+      in stdenv.mkDerivation rec {
+        pname = "gawkextlib-${name}";
+        version = "unstable-2019-11-21";
+
+        src = fetchgit {
+          url = "git://git.code.sf.net/p/gawkextlib/code";
+          rev = "f70f10da2804e4fd0a0bac57736e9c1cf21e345d";
+          sha256 = "0r8fz89n3l4dfszs1980yqj0ah95430lj0y1lb7blfkwxa6c2xik";
+        };
+
+        postPatch = ''
+          cd ${name}
+        '';
+
+        nativeBuildInputs = [
+          autoconf
+          automake
+          libtool
+          autoreconfHook
+          pkg-config
+          texinfo
+          gettext
+        ];
+
+        buildInputs = [ gawk ] ++ extraBuildInputs;
+        propagatedBuildInputs = lib.optional is_extension gawkextlib;
+
+        setupHook = if is_extension then ./setup-hook.sh else null;
+        inherit gawk;
+
+        inherit doCheck;
+        checkInputs = [ more ];
+
+        meta = with lib; {
+          homepage = "https://sourceforge.net/projects/gawkextlib/";
+          description = "Dynamically loaded extension libraries for GNU AWK";
+          longDescription = ''
+            The gawkextlib project provides several extension libraries for
+            gawk (GNU AWK), as well as libgawkextlib containing some APIs that
+            are useful for building gawk extension libraries. These libraries
+            enable gawk to process XML data, interact with a PostgreSQL
+            database, use the GD graphics library, and perform unlimited
+            precision MPFR calculations.
+          '';
+          license = licenses.gpl3Plus;
+          platforms = platforms.unix;
+          maintainers = with maintainers; [ tomberek ];
+        };
+      });
+  gawkextlib = buildExtension {
+    gawkextlib = null;
+    name = "lib";
+  };
+  libs = {
+    abort = buildExtension {
+      inherit gawkextlib;
+      name = "abort";
+    };
+    aregex = buildExtension {
+      inherit gawkextlib;
+      name = "aregex";
+      extraBuildInputs = [ tre ];
+    };
+    csv = buildExtension {
+      inherit gawkextlib;
+      name = "csv";
+    };
+    errno = buildExtension {
+      inherit gawkextlib;
+      name = "errno";
+    };
+    gd = buildExtension {
+      inherit gawkextlib;
+      name = "gd";
+      extraBuildInputs = [ gd ];
+    };
+    haru = buildExtension {
+      inherit gawkextlib;
+      name = "haru";
+      extraBuildInputs = [ libharu ];
+    };
+    json = buildExtension {
+      inherit gawkextlib;
+      name = "json";
+      extraBuildInputs = [ rapidjson ];
+    };
+    lmdb = buildExtension {
+      inherit gawkextlib;
+      name = "lmdb";
+      extraBuildInputs = [ lmdb ];
+      #  mdb_env_open(env, /dev/null)
+      #! No such device
+      #  mdb_env_open(env, /dev/null)
+      #! Operation not supported by device
+      doCheck = !stdenv.isDarwin;
+    };
+    mbs = buildExtension {
+      inherit gawkextlib;
+      name = "mbs";
+      extraBuildInputs = [ glibcLocales ];
+      #! "spät": length: 5, mbs_length: 6, wcswidth: 4
+      doCheck = !stdenv.isDarwin;
+    };
+    mpfr = buildExtension {
+      inherit gawkextlib;
+      name = "mpfr";
+      extraBuildInputs = [ gmp mpfr ];
+    };
+    nl_langinfo = buildExtension {
+      inherit gawkextlib;
+      name = "nl_langinfo";
+    };
+    pgsql = buildExtension {
+      inherit gawkextlib;
+      name = "pgsql";
+      extraBuildInputs = [ postgresql ];
+    };
+    redis = buildExtension {
+      inherit gawkextlib;
+      name = "redis";
+      extraBuildInputs = [ hiredis ];
+    };
+    select = buildExtension {
+      inherit gawkextlib;
+      name = "select";
+    };
+    timex = buildExtension {
+      inherit gawkextlib;
+      name = "timex";
+    };
+    xml = buildExtension {
+      inherit gawkextlib;
+      name = "xml";
+      extraBuildInputs = [ expat libiconv ];
+    };
+  };
+in recurseIntoAttrs (libs // {
+  inherit gawkextlib buildExtension;
+  full = builtins.attrValues libs;
+})
diff --git a/nixpkgs/pkgs/tools/text/gawk/setup-hook.sh b/nixpkgs/pkgs/tools/text/gawk/setup-hook.sh
new file mode 100644
index 000000000000..d568cb8c7dd9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gawk/setup-hook.sh
@@ -0,0 +1,6 @@
+local oldOpts="-u"
+shopt -qo nounset || oldOpts="+u"
+set +u
+. @gawk@/etc/profile.d/gawk.sh
+gawklibpath_append @out@/lib/gawk
+set "$oldOpts"
diff --git a/nixpkgs/pkgs/tools/text/gist/default.nix b/nixpkgs/pkgs/tools/text/gist/default.nix
new file mode 100644
index 000000000000..d2676b379970
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gist/default.nix
@@ -0,0 +1,17 @@
+{ buildRubyGem, lib, ruby }:
+
+buildRubyGem rec {
+  inherit ruby;
+  name = "${gemName}-${version}";
+  gemName = "gist";
+  version = "6.0.0";
+  source.sha256 = "0qnd1jqd7b04871v4l73grcmi7c0pivm8nsfrqvwivm4n4b3c2hd";
+
+  meta = with lib; {
+    description = "Upload code to https://gist.github.com (or github enterprise)";
+    homepage = "http://defunkt.io/gist/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ zimbatm ];
+    platforms = ruby.meta.platforms;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gjo/default.nix b/nixpkgs/pkgs/tools/text/gjo/default.nix
new file mode 100644
index 000000000000..da8fa212940a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gjo/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, buildGoModule
+, fetchFromGitHub
+}:
+
+buildGoModule rec {
+  pname = "gjo";
+  version = "1.0.3";
+
+  src = fetchFromGitHub {
+    owner = "skanehira";
+    repo = "gjo";
+    rev = version;
+    sha256 = "07halr0jzds4rya6hlvp45bjf7vg4yf49w5q60mch05hk8qkjjdw";
+  };
+
+  vendorSha256 = null;
+
+  meta = with lib; {
+    description = "Small utility to create JSON objects";
+    homepage = "https://github.com/skanehira/gjo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ doronbehar ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/glogg/default.nix b/nixpkgs/pkgs/tools/text/glogg/default.nix
new file mode 100644
index 000000000000..306c25498ad3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/glogg/default.nix
@@ -0,0 +1,41 @@
+{ mkDerivation, lib, stdenv, fetchFromGitHub, qmake, boost }:
+
+mkDerivation rec {
+  pname = "glogg";
+  version = "1.1.4";
+
+  src = fetchFromGitHub {
+    owner = "nickbnf";
+    repo = "glogg";
+    rev = "v${version}";
+    sha256 = "0hf1c2m8n88frmxmyn0ndr8129p7iky49nq565sw1asaydm5z6pb";
+  };
+
+  postPatch = lib.optionalString stdenv.isDarwin ''
+    substituteInPlace glogg.pro \
+      --replace "boost_program_options-mt" "boost_program_options"
+  '';
+
+  nativeBuildInputs = [ qmake ];
+  buildInputs = [ boost ];
+
+  qmakeFlags = [ "VERSION=${version}" ];
+
+  postInstall = lib.optionalString stdenv.isDarwin ''
+    mkdir -p $out/Applications
+    mv $out/bin/glogg.app $out/Applications/glogg.app
+    rm -fr $out/{bin,share}
+    wrapQtApp $out/Applications/glogg.app/Contents/MacOS/glogg
+  '';
+
+  meta = with lib; {
+    description = "The fast, smart log explorer";
+    longDescription = ''
+      A multi-platform GUI application to browse and search through long or complex log files. It is designed with programmers and system administrators in mind. glogg can be seen as a graphical, interactive combination of grep and less.
+    '';
+    homepage = "https://glogg.bonnefon.org/";
+    license = licenses.gpl3Plus;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ c0bw3b ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gnugrep/default.nix b/nixpkgs/pkgs/tools/text/gnugrep/default.nix
new file mode 100644
index 000000000000..c5a661af1153
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnugrep/default.nix
@@ -0,0 +1,67 @@
+{ lib, stdenv, fetchurl, pcre, libiconv, perl }:
+
+# Note: this package is used for bootstrapping fetchurl, and thus
+# cannot use fetchpatch! All mutable patches (generated by GitHub or
+# cgit) that are needed here should be included directly in Nixpkgs as
+# files.
+
+let version = "3.6"; in
+
+stdenv.mkDerivation {
+  pname = "gnugrep";
+  inherit version;
+
+  src = fetchurl {
+    url = "mirror://gnu/grep/grep-${version}.tar.xz";
+    sha256 = "0gipv6bzkm1aihj0ncqpyh164xrzgcxcv9r1kwzyk2g1mzl1azk6";
+  };
+
+  # Perl is needed for testing
+  nativeBuildInputs = [ perl ];
+  outputs = [ "out" "info" ]; # the man pages are rather small
+
+  buildInputs = [ pcre libiconv ];
+
+  # cygwin: FAIL: multibyte-white-space
+  # freebsd: FAIL mb-non-UTF8-performance
+  # all platforms: timing sensitivity in long-pattern-perf
+  #doCheck = !stdenv.isDarwin && !stdenv.isSunOS && !stdenv.isCygwin && !stdenv.isFreeBSD;
+  doCheck = false;
+
+  # On macOS, force use of mkdir -p, since Grep's fallback
+  # (./install-sh) is broken.
+  preConfigure = ''
+    export MKDIR_P="mkdir -p"
+  '';
+
+  # Fix reference to sh in bootstrap-tools, and invoke grep via
+  # absolute path rather than looking at argv[0].
+  postInstall =
+    ''
+      rm $out/bin/egrep $out/bin/fgrep
+      echo "#! /bin/sh" > $out/bin/egrep
+      echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep
+      echo "#! /bin/sh" > $out/bin/fgrep
+      echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep
+      chmod +x $out/bin/egrep $out/bin/fgrep
+    '';
+
+  meta = with lib; {
+    homepage = "https://www.gnu.org/software/grep/";
+    description = "GNU implementation of the Unix grep command";
+
+    longDescription = ''
+      The grep command searches one or more input files for lines
+      containing a match to a specified pattern.  By default, grep
+      prints the matching lines.
+    '';
+
+    license = licenses.gpl3Plus;
+
+    maintainers = [ maintainers.eelco ];
+    platforms = platforms.all;
+    mainProgram = "grep";
+  };
+
+  passthru = {inherit pcre;};
+}
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/Allow_input_files_to_be_missing_for_ed-style_patches.patch b/nixpkgs/pkgs/tools/text/gnupatch/Allow_input_files_to_be_missing_for_ed-style_patches.patch
new file mode 100644
index 000000000000..98c9aa877a72
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/Allow_input_files_to_be_missing_for_ed-style_patches.patch
@@ -0,0 +1,33 @@
+From b5a91a01e5d0897facdd0f49d64b76b0f02b43e1 Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Fri, 6 Apr 2018 11:34:51 +0200
+Subject: Allow input files to be missing for ed-style patches
+
+* src/pch.c (do_ed_script): Allow input files to be missing so that new
+files will be created as with non-ed-style patches.
+---
+ src/pch.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/pch.c b/src/pch.c
+index bc6278c..0c5cc26 100644
+--- a/src/pch.c
++++ b/src/pch.c
+@@ -2394,9 +2394,11 @@ do_ed_script (char const *inname, char const *outname,
+ 
+     if (! dry_run && ! skip_rest_of_patch) {
+ 	int exclusive = *outname_needs_removal ? 0 : O_EXCL;
+-	assert (! inerrno);
+-	*outname_needs_removal = true;
+-	copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
++	if (inerrno != ENOENT)
++	  {
++	    *outname_needs_removal = true;
++	    copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
++	  }
+ 	sprintf (buf, "%s %s%s", editor_program,
+ 		 verbosity == VERBOSE ? "" : "- ",
+ 		 outname);
+-- 
+cgit v1.0-41-gc330
+
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-1000156.patch b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-1000156.patch
new file mode 100644
index 000000000000..36f33dea2b90
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-1000156.patch
@@ -0,0 +1,211 @@
+From 123eaff0d5d1aebe128295959435b9ca5909c26d Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Fri, 6 Apr 2018 12:14:49 +0200
+Subject: Fix arbitrary command execution in ed-style patches
+ (CVE-2018-1000156)
+
+* src/pch.c (do_ed_script): Write ed script to a temporary file instead
+of piping it to ed: this will cause ed to abort on invalid commands
+instead of rejecting them and carrying on.
+* tests/ed-style: New test case.
+* tests/Makefile.am (TESTS): Add test case.
+---
+ src/pch.c         | 91 ++++++++++++++++++++++++++++++++++++++++---------------
+ tests/Makefile.am |  1 +
+ tests/ed-style    | 41 +++++++++++++++++++++++++
+ 3 files changed, 108 insertions(+), 25 deletions(-)
+ create mode 100644 tests/ed-style
+
+diff --git a/src/pch.c b/src/pch.c
+index 0c5cc26..4fd5a05 100644
+--- a/src/pch.c
++++ b/src/pch.c
+@@ -33,6 +33,7 @@
+ # include <io.h>
+ #endif
+ #include <safe.h>
++#include <sys/wait.h>
+ 
+ #define INITHUNKMAX 125			/* initial dynamic allocation size */
+ 
+@@ -2389,24 +2390,28 @@ do_ed_script (char const *inname, char const *outname,
+     static char const editor_program[] = EDITOR_PROGRAM;
+ 
+     file_offset beginning_of_this_line;
+-    FILE *pipefp = 0;
+     size_t chars_read;
++    FILE *tmpfp = 0;
++    char const *tmpname;
++    int tmpfd;
++    pid_t pid;
++
++    if (! dry_run && ! skip_rest_of_patch)
++      {
++	/* Write ed script to a temporary file.  This causes ed to abort on
++	   invalid commands such as when line numbers or ranges exceed the
++	   number of available lines.  When ed reads from a pipe, it rejects
++	   invalid commands and treats the next line as a new command, which
++	   can lead to arbitrary command execution.  */
++
++	tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
++	if (tmpfd == -1)
++	  pfatal ("Can't create temporary file %s", quotearg (tmpname));
++	tmpfp = fdopen (tmpfd, "w+b");
++	if (! tmpfp)
++	  pfatal ("Can't open stream for file %s", quotearg (tmpname));
++      }
+ 
+-    if (! dry_run && ! skip_rest_of_patch) {
+-	int exclusive = *outname_needs_removal ? 0 : O_EXCL;
+-	if (inerrno != ENOENT)
+-	  {
+-	    *outname_needs_removal = true;
+-	    copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
+-	  }
+-	sprintf (buf, "%s %s%s", editor_program,
+-		 verbosity == VERBOSE ? "" : "- ",
+-		 outname);
+-	fflush (stdout);
+-	pipefp = popen(buf, binary_transput ? "wb" : "w");
+-	if (!pipefp)
+-	  pfatal ("Can't open pipe to %s", quotearg (buf));
+-    }
+     for (;;) {
+ 	char ed_command_letter;
+ 	beginning_of_this_line = file_tell (pfp);
+@@ -2417,14 +2422,14 @@ do_ed_script (char const *inname, char const *outname,
+ 	}
+ 	ed_command_letter = get_ed_command_letter (buf);
+ 	if (ed_command_letter) {
+-	    if (pipefp)
+-		if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
++	    if (tmpfp)
++		if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
+ 		    write_fatal ();
+ 	    if (ed_command_letter != 'd' && ed_command_letter != 's') {
+ 	        p_pass_comments_through = true;
+ 		while ((chars_read = get_line ()) != 0) {
+-		    if (pipefp)
+-			if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
++		    if (tmpfp)
++			if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
+ 			    write_fatal ();
+ 		    if (chars_read == 2  &&  strEQ (buf, ".\n"))
+ 			break;
+@@ -2437,13 +2442,49 @@ do_ed_script (char const *inname, char const *outname,
+ 	    break;
+ 	}
+     }
+-    if (!pipefp)
++    if (!tmpfp)
+       return;
+-    if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0
+-	|| fflush (pipefp) != 0)
++    if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0
++	|| fflush (tmpfp) != 0)
+       write_fatal ();
+-    if (pclose (pipefp) != 0)
+-      fatal ("%s FAILED", editor_program);
++
++    if (lseek (tmpfd, 0, SEEK_SET) == -1)
++      pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
++
++    if (! dry_run && ! skip_rest_of_patch) {
++	int exclusive = *outname_needs_removal ? 0 : O_EXCL;
++	*outname_needs_removal = true;
++	if (inerrno != ENOENT)
++	  {
++	    *outname_needs_removal = true;
++	    copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
++	  }
++	sprintf (buf, "%s %s%s", editor_program,
++		 verbosity == VERBOSE ? "" : "- ",
++		 outname);
++	fflush (stdout);
++
++	pid = fork();
++	if (pid == -1)
++	  pfatal ("Can't fork");
++	else if (pid == 0)
++	  {
++	    dup2 (tmpfd, 0);
++	    execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
++	    _exit (2);
++	  }
++	else
++	  {
++	    int wstatus;
++	    if (waitpid (pid, &wstatus, 0) == -1
++	        || ! WIFEXITED (wstatus)
++		|| WEXITSTATUS (wstatus) != 0)
++	      fatal ("%s FAILED", editor_program);
++	  }
++    }
++
++    fclose (tmpfp);
++    safe_unlink (tmpname);
+ 
+     if (ofp)
+       {
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 6b6df63..16f8693 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -32,6 +32,7 @@ TESTS = \
+ 	crlf-handling \
+ 	dash-o-append \
+ 	deep-directories \
++	ed-style \
+ 	empty-files \
+ 	false-match \
+ 	fifo \
+diff --git a/tests/ed-style b/tests/ed-style
+new file mode 100644
+index 0000000..d8c0689
+--- /dev/null
++++ b/tests/ed-style
+@@ -0,0 +1,41 @@
++# Copyright (C) 2018 Free Software Foundation, Inc.
++#
++# Copying and distribution of this file, with or without modification,
++# in any medium, are permitted without royalty provided the copyright
++# notice and this notice are preserved.
++
++. $srcdir/test-lib.sh
++
++require cat
++use_local_patch
++use_tmpdir
++
++# ==============================================================
++
++cat > ed1.diff <<EOF
++0a
++foo
++.
++EOF
++
++check 'patch -e foo -i ed1.diff' <<EOF
++EOF
++
++check 'cat foo' <<EOF
++foo
++EOF
++
++cat > ed2.diff <<EOF
++1337a
++r !echo bar
++,p
++EOF
++
++check 'patch -e foo -i ed2.diff 2> /dev/null || echo "Status: $?"' <<EOF
++?
++Status: 2
++EOF
++
++check 'cat foo' <<EOF
++foo
++EOF
+-- 
+cgit v1.0-41-gc330
+
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6951.patch b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6951.patch
new file mode 100644
index 000000000000..22d5f061c332
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6951.patch
@@ -0,0 +1,28 @@
+From f290f48a621867084884bfff87f8093c15195e6a Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Mon, 12 Feb 2018 16:48:24 +0100
+Subject: Fix segfault with mangled rename patch
+
+http://savannah.gnu.org/bugs/?53132
+* src/pch.c (intuit_diff_type): Ensure that two filenames are specified
+for renames and copies (fix the existing check).
+---
+ src/pch.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/pch.c b/src/pch.c
+index ff9ed2c..bc6278c 100644
+--- a/src/pch.c
++++ b/src/pch.c
+@@ -974,7 +974,8 @@ intuit_diff_type (bool need_header, mode_t *p_file_type)
+     if ((pch_rename () || pch_copy ())
+ 	&& ! inname
+ 	&& ! ((i == OLD || i == NEW) &&
+-	      p_name[! reverse] &&
++	      p_name[reverse] && p_name[! reverse] &&
++	      name_is_valid (p_name[reverse]) &&
+ 	      name_is_valid (p_name[! reverse])))
+       {
+ 	say ("Cannot %s file without two valid file names\n", pch_rename () ? "rename" : "copy");
+-- 
+cgit v1.0-41-gc330
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6952.patch b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6952.patch
new file mode 100644
index 000000000000..2da323c69844
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2018-6952.patch
@@ -0,0 +1,28 @@
+From 9c986353e420ead6e706262bf204d6e03322c300 Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Fri, 17 Aug 2018 13:35:40 +0200
+Subject: Fix swapping fake lines in pch_swap
+
+* src/pch.c (pch_swap): Fix swapping p_bfake and p_efake when there is a
+blank line in the middle of a context-diff hunk: that empty line stays
+in the middle of the hunk and isn't swapped.
+
+Fixes: https://savannah.gnu.org/bugs/index.php?53133
+---
+ src/pch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/pch.c b/src/pch.c
+index e92bc64..a500ad9 100644
+--- a/src/pch.c
++++ b/src/pch.c
+@@ -2122,7 +2122,7 @@ pch_swap (void)
+     }
+     if (p_efake >= 0) {			/* fix non-freeable ptr range */
+ 	if (p_efake <= i)
+-	    n = p_end - i + 1;
++	    n = p_end - p_ptrn_lines;
+ 	else
+ 	    n = -i;
+ 	p_efake += n;
+-- 
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13636.patch b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13636.patch
new file mode 100644
index 000000000000..e62c3d41753c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13636.patch
@@ -0,0 +1,108 @@
+From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Mon, 15 Jul 2019 16:21:48 +0200
+Subject: Don't follow symlinks unless --follow-symlinks is given
+
+* src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file,
+append_to_file): Unless the --follow-symlinks option is given, open files with
+the O_NOFOLLOW flag to avoid following symlinks.  So far, we were only doing
+that consistently for input files.
+* src/util.c (create_backup): When creating empty backup files, (re)create them
+with O_CREAT | O_EXCL to avoid following symlinks in that case as well.
+---
+ src/inp.c  | 12 ++++++++++--
+ src/util.c | 14 +++++++++++---
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/src/inp.c b/src/inp.c
+index 32d0919..22d7473 100644
+--- a/src/inp.c
++++ b/src/inp.c
+@@ -238,8 +238,13 @@ plan_a (char const *filename)
+     {
+       if (S_ISREG (instat.st_mode))
+         {
+-	  int ifd = safe_open (filename, O_RDONLY|binary_transput, 0);
++	  int flags = O_RDONLY | binary_transput;
+ 	  size_t buffered = 0, n;
++	  int ifd;
++
++	  if (! follow_symlinks)
++	    flags |= O_NOFOLLOW;
++	  ifd = safe_open (filename, flags, 0);
+ 	  if (ifd < 0)
+ 	    pfatal ("can't open file %s", quotearg (filename));
+ 
+@@ -340,6 +345,7 @@ plan_a (char const *filename)
+ static void
+ plan_b (char const *filename)
+ {
++  int flags = O_RDONLY | binary_transput;
+   int ifd;
+   FILE *ifp;
+   int c;
+@@ -353,7 +359,9 @@ plan_b (char const *filename)
+ 
+   if (instat.st_size == 0)
+     filename = NULL_DEVICE;
+-  if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0
++  if (! follow_symlinks)
++    flags |= O_NOFOLLOW;
++  if ((ifd = safe_open (filename, flags, 0)) < 0
+       || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r")))
+     pfatal ("Can't open file %s", quotearg (filename));
+   if (TMPINNAME_needs_removal)
+diff --git a/src/util.c b/src/util.c
+index 1cc08ba..fb38307 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -388,7 +388,7 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original)
+ 
+ 	  try_makedirs_errno = ENOENT;
+ 	  safe_unlink (bakname);
+-	  while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0)
++	  while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0)
+ 	    {
+ 	      if (errno != try_makedirs_errno)
+ 		pfatal ("Can't create file %s", quotearg (bakname));
+@@ -579,10 +579,13 @@ create_file (char const *file, int open_flags, mode_t mode,
+ static void
+ copy_to_fd (const char *from, int tofd)
+ {
++  int from_flags = O_RDONLY | O_BINARY;
+   int fromfd;
+   ssize_t i;
+ 
+-  if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0)
++  if (! follow_symlinks)
++    from_flags |= O_NOFOLLOW;
++  if ((fromfd = safe_open (from, from_flags, 0)) < 0)
+     pfatal ("Can't reopen file %s", quotearg (from));
+   while ((i = read (fromfd, buf, bufsize)) != 0)
+     {
+@@ -625,6 +628,8 @@ copy_file (char const *from, char const *to, struct stat *tost,
+   else
+     {
+       assert (S_ISREG (mode));
++      if (! follow_symlinks)
++	to_flags |= O_NOFOLLOW;
+       tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode,
+ 			  to_dir_known_to_exist);
+       copy_to_fd (from, tofd);
+@@ -640,9 +645,12 @@ copy_file (char const *from, char const *to, struct stat *tost,
+ void
+ append_to_file (char const *from, char const *to)
+ {
++  int to_flags = O_WRONLY | O_APPEND | O_BINARY;
+   int tofd;
+ 
+-  if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0)
++  if (! follow_symlinks)
++    to_flags |= O_NOFOLLOW;
++  if ((tofd = safe_open (to, to_flags, 0)) < 0)
+     pfatal ("Can't reopen file %s", quotearg (to));
+   copy_to_fd (from, tofd);
+   if (close (tofd) != 0)
+-- 
+cgit v1.0-41-gc330
+
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13638-and-CVE-2018-20969.patch b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13638-and-CVE-2018-20969.patch
new file mode 100644
index 000000000000..38caff628aaf
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/CVE-2019-13638-and-CVE-2018-20969.patch
@@ -0,0 +1,38 @@
+From 3fcd042d26d70856e826a42b5f93dc4854d80bf0 Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@gnu.org>
+Date: Fri, 6 Apr 2018 19:36:15 +0200
+Subject: Invoke ed directly instead of using the shell
+
+* src/pch.c (do_ed_script): Invoke ed directly instead of using a shell
+command to avoid quoting vulnerabilities.
+---
+ src/pch.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/pch.c b/src/pch.c
+index 4fd5a05..16e001a 100644
+--- a/src/pch.c
++++ b/src/pch.c
+@@ -2459,9 +2459,6 @@ do_ed_script (char const *inname, char const *outname,
+ 	    *outname_needs_removal = true;
+ 	    copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
+ 	  }
+-	sprintf (buf, "%s %s%s", editor_program,
+-		 verbosity == VERBOSE ? "" : "- ",
+-		 outname);
+ 	fflush (stdout);
+ 
+ 	pid = fork();
+@@ -2470,7 +2467,8 @@ do_ed_script (char const *inname, char const *outname,
+ 	else if (pid == 0)
+ 	  {
+ 	    dup2 (tmpfd, 0);
+-	    execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
++	    assert (outname[0] != '!' && outname[0] != '-');
++	    execlp (editor_program, editor_program, "-", outname, (char  *) NULL);
+ 	    _exit (2);
+ 	  }
+ 	else
+-- 
+cgit v1.0-41-gc330
+
diff --git a/nixpkgs/pkgs/tools/text/gnupatch/default.nix b/nixpkgs/pkgs/tools/text/gnupatch/default.nix
new file mode 100644
index 000000000000..8d8fa7d0a8ba
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnupatch/default.nix
@@ -0,0 +1,59 @@
+{ lib, stdenv, fetchurl
+, ed, autoreconfHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "patch";
+  version = "2.7.6";
+
+  src = fetchurl {
+    url = "mirror://gnu/patch/patch-${version}.tar.xz";
+    sha256 = "1zfqy4rdcy279vwn2z1kbv19dcfw25d2aqy9nzvdkq5bjzd0nqdc";
+  };
+
+  patches = [
+    # https://git.savannah.gnu.org/cgit/patch.git/patch/?id=f290f48a621867084884bfff87f8093c15195e6a
+    ./CVE-2018-6951.patch
+
+    # https://git.savannah.gnu.org/cgit/patch.git/patch/?id=b5a91a01e5d0897facdd0f49d64b76b0f02b43e1
+    ./Allow_input_files_to_be_missing_for_ed-style_patches.patch
+
+    # https://git.savannah.gnu.org/cgit/patch.git/patch/?id=123eaff0d5d1aebe128295959435b9ca5909c26d
+    ./CVE-2018-1000156.patch
+
+    # https://git.savannah.gnu.org/cgit/patch.git/commit/?id=9c986353e420ead6e706262bf204d6e03322c300
+    ./CVE-2018-6952.patch
+
+    # https://git.savannah.gnu.org/cgit/patch.git/patch/?id=dce4683cbbe107a95f1f0d45fabc304acfb5d71a
+    ./CVE-2019-13636.patch
+
+    # https://git.savannah.gnu.org/cgit/patch.git/patch/?id=3fcd042d26d70856e826a42b5f93dc4854d80bf0
+    ./CVE-2019-13638-and-CVE-2018-20969.patch
+  ];
+
+  nativeBuildInputs = [ autoreconfHook ];
+
+  configureFlags = lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
+    "ac_cv_func_strnlen_working=yes"
+  ];
+
+  doCheck = stdenv.hostPlatform.libc != "musl"; # not cross;
+  checkInputs = [ed];
+
+  meta = {
+    description = "GNU Patch, a program to apply differences to files";
+
+    longDescription =
+      '' GNU Patch takes a patch file containing a difference listing
+         produced by the diff program and applies those differences to one or
+         more original files, producing patched versions.
+      '';
+
+    homepage = "https://savannah.gnu.org/projects/patch";
+
+    license = lib.licenses.gpl3Plus;
+
+    maintainers = [ ];
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gnused/422.nix b/nixpkgs/pkgs/tools/text/gnused/422.nix
new file mode 100644
index 000000000000..80aa9f654a6a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnused/422.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation {
+  name = "gnused-4.2.2";
+
+  src = fetchurl {
+    url = "mirror://gnu/sed/sed-4.2.2.tar.bz2";
+    sha256 = "f048d1838da284c8bc9753e4506b85a1e0cc1ea8999d36f6995bcb9460cddbd7";
+  };
+
+  configureFlags = lib.optional stdenv.hostPlatform.isMinGW "ac_cv_func__set_invalid_parameter_handler=no";
+
+  outputs = [ "out" "info" ];
+
+  meta = {
+    homepage = "https://www.gnu.org/software/sed/";
+    description = "GNU sed, a batch stream editor";
+
+    longDescription = ''
+      Sed (stream editor) isn't really a true text editor or text
+      processor.  Instead, it is used to filter text, i.e., it takes
+      text input and performs some operation (or set of operations) on
+      it and outputs the modified text.  Sed is typically used for
+      extracting part of a file using pattern matching or substituting
+      multiple occurrences of a string within a file.
+    '';
+
+    license = lib.licenses.gpl3Plus;
+
+    platforms = lib.platforms.all;
+    maintainers = [ ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gnused/default.nix b/nixpkgs/pkgs/tools/text/gnused/default.nix
new file mode 100644
index 000000000000..23b2794bf13f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gnused/default.nix
@@ -0,0 +1,38 @@
+{ lib, stdenv, fetchurl, perl }:
+
+stdenv.mkDerivation rec {
+  pname = "gnused";
+  version = "4.8";
+
+  src = fetchurl {
+    url = "mirror://gnu/sed/sed-${version}.tar.xz";
+    sha256 = "0cznxw73fzv1n3nj2zsq6nf73rvsbxndp444xkpahdqvlzz0r6zp";
+  };
+
+  outputs = [ "out" "info" ];
+
+  nativeBuildInputs = [ perl ];
+  preConfigure = "patchShebangs ./build-aux/help2man";
+
+  # Prevents attempts of running 'help2man' on cross-built binaries.
+  PERL = if stdenv.hostPlatform == stdenv.buildPlatform then null else "missing";
+
+  meta = {
+    homepage = "https://www.gnu.org/software/sed/";
+    description = "GNU sed, a batch stream editor";
+
+    longDescription = ''
+      Sed (stream editor) isn't really a true text editor or text
+      processor.  Instead, it is used to filter text, i.e., it takes
+      text input and performs some operation (or set of operations) on
+      it and outputs the modified text.  Sed is typically used for
+      extracting part of a file using pattern matching or substituting
+      multiple occurrences of a string within a file.
+    '';
+
+    license = lib.licenses.gpl3Plus;
+
+    platforms = lib.platforms.unix;
+    maintainers = with lib.maintainers; [ mic92 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gpt2tc/0001-add-python-shebang.patch b/nixpkgs/pkgs/tools/text/gpt2tc/0001-add-python-shebang.patch
new file mode 100644
index 000000000000..b47b444009ac
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gpt2tc/0001-add-python-shebang.patch
@@ -0,0 +1,10 @@
+diff --git a/gpt2convert.py b/gpt2convert.py
+index 34ca909..6e6cac5 100644
+--- a/gpt2convert.py
++++ b/gpt2convert.py
+@@ -1,3 +1,5 @@
++#!/usr/bin/env python3
++
+ import sys
+ import tensorflow as tf
+ import numpy as np
diff --git a/nixpkgs/pkgs/tools/text/gpt2tc/default.nix b/nixpkgs/pkgs/tools/text/gpt2tc/default.nix
new file mode 100644
index 000000000000..3714a4185485
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gpt2tc/default.nix
@@ -0,0 +1,44 @@
+{ lib, stdenv, fetchurl, autoPatchelfHook, python3 }:
+
+stdenv.mkDerivation rec {
+  pname = "gpt2tc";
+  version = "2021-04-24";
+
+  src = fetchurl {
+    url = "https://bellard.org/libnc/gpt2tc-${version}.tar.gz";
+    hash = "sha256-kHnRziSNRewifM/oKDQwG27rXRvntuUUX8M+PUNHpA4=";
+  };
+
+  patches = [
+    # Add a shebang to the python script so that nix detects it as such and
+    # wraps it properly. Otherwise, it runs in shell and freezes the system.
+    ./0001-add-python-shebang.patch
+  ];
+
+  nativeBuildInputs = [ autoPatchelfHook ];
+
+  buildInputs = [
+    (python3.withPackages (p: with p; [ numpy tensorflow ]))
+  ];
+
+  installPhase = ''
+    runHook preInstall
+
+    install -D -m755 -t $out/lib libnc${stdenv.hostPlatform.extensions.sharedLibrary}
+    addAutoPatchelfSearchPath $out/lib
+    install -D -m755 -t $out/bin gpt2tc
+    install -T -m755 download_model.sh $out/bin/gpt2-download-model
+    install -T -m755 gpt2convert.py $out/bin/gpt2-convert
+    install -D -m644 -t $out/share/gpt2tc readme.txt gpt2vocab.txt Changelog
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "Text completion and compression using GPT-2";
+    homepage = "https://bellard.org/nncp/gpt2tc.html";
+    license = licenses.unfree;
+    platforms = [ "x86_64-linux" ];
+    maintainers = with maintainers; [ anna328p ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/grin/default.nix b/nixpkgs/pkgs/tools/text/grin/default.nix
new file mode 100644
index 000000000000..5d89619001b4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/grin/default.nix
@@ -0,0 +1,24 @@
+{ lib, fetchFromGitHub, python2Packages }:
+
+python2Packages.buildPythonApplication rec {
+  program = "grin";
+  version = "1.2.1";
+  name = "${program}-${version}";
+  namePrefix = "";
+
+  src = fetchFromGitHub {
+    owner = "rkern";
+    repo = program;
+    rev = "8dd4b5309b3bc04fe9d3e71836420f7d8d4a293f";
+    sha256 = "0vz2aahwdcy1296g4w3i79dkvmzk9jc2n2zmlcvlg5m3s6h7b6jd";
+  };
+
+  buildInputs = with python2Packages; [ nose ];
+
+  meta = {
+    homepage = "https://github.com/rkern/grin";
+    description = "A grep program configured the way I like it";
+    platforms = lib.platforms.all;
+    maintainers = [ lib.maintainers.sjagoe ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/grip-search/default.nix b/nixpkgs/pkgs/tools/text/grip-search/default.nix
new file mode 100644
index 000000000000..57f0139dbc98
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/grip-search/default.nix
@@ -0,0 +1,31 @@
+{ lib, stdenv, fetchFromGitHub, boost, pkg-config, cmake, catch2 }:
+
+stdenv.mkDerivation rec {
+  pname = "grip-search";
+  version = "0.8";
+
+  src = fetchFromGitHub {
+    owner = "sc0ty";
+    repo = "grip";
+    rev = "v${version}";
+    sha256 = "0bkqarylgzhis6fpj48qbifcd6a26cgnq8784hgnm707rq9kb0rx";
+  };
+
+  nativeBuildInputs = [ pkg-config cmake catch2 ];
+
+  doCheck = true;
+
+  buildInputs = [ boost ];
+
+  patchPhase = ''
+    substituteInPlace src/general/config.h --replace "CUSTOM-BUILD" "${version}"
+  '';
+
+  meta = with lib; {
+    description = "Fast, indexed regexp search over large file trees";
+    homepage = "https://github.com/sc0ty/grip";
+    license = licenses.gpl3;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ tex ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/groff/0001-Fix-cross-compilation-by-looking-for-ar.patch b/nixpkgs/pkgs/tools/text/groff/0001-Fix-cross-compilation-by-looking-for-ar.patch
new file mode 100644
index 000000000000..671293cda5b1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/groff/0001-Fix-cross-compilation-by-looking-for-ar.patch
@@ -0,0 +1,46 @@
+From 1454525f70b43a6957b7c9e1870e997368787da3 Mon Sep 17 00:00:00 2001
+From: Samuel Dionne-Riel <samuel@dionne-riel.com>
+Date: Fri, 8 Nov 2019 21:59:21 -0500
+Subject: [PATCH] Fix cross-compilation by looking for `ar`.
+
+---
+ Makefile.am  | 2 +-
+ configure.ac | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index d18c49b8..b1b53338 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -494,7 +494,7 @@ CCC=@CXX@
+ # INSTALL_INFO
+ # LN_S
+ 
+-AR=ar
++AR=@AR@
+ ETAGS=etags
+ ETAGSFLAGS=
+ # Flag that tells etags to assume C++.
+diff --git a/configure.ac b/configure.ac
+index 28e75f17..2449b9f5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -37,6 +37,7 @@ AC_CONFIG_AUX_DIR([build-aux])
+ 
+ AC_CONFIG_HEADERS([src/include/config.h:src/include/config.hin])
+ AC_CONFIG_SRCDIR([src/roff/groff/groff.cpp])
++AC_CONFIG_MACRO_DIR([m4])
+ 
+ AC_USE_SYSTEM_EXTENSIONS
+ 
+@@ -72,6 +73,7 @@ GROFF_DOC_CHECK
+ GROFF_MAKEINFO
+ GROFF_TEXI2DVI
+ AC_PROG_RANLIB
++AC_CHECK_TOOL([AR], [ar], [ar])
+ GROFF_INSTALL_SH
+ GROFF_INSTALL_INFO
+ AC_PROG_INSTALL
+-- 
+2.23.0
+
diff --git a/nixpkgs/pkgs/tools/text/groff/default.nix b/nixpkgs/pkgs/tools/text/groff/default.nix
new file mode 100644
index 000000000000..5b158f2cbb0e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/groff/default.nix
@@ -0,0 +1,134 @@
+{ lib, stdenv, fetchurl, fetchpatch, perl
+, ghostscript #for postscript and html output
+, psutils, netpbm #for html output
+, buildPackages
+, autoreconfHook
+, pkg-config
+, texinfo
+}:
+
+stdenv.mkDerivation rec {
+  pname = "groff";
+  version = "1.22.4";
+
+  src = fetchurl {
+    url = "mirror://gnu/groff/${pname}-${version}.tar.gz";
+    sha256 = "14q2mldnr1vx0l9lqp9v2f6iww24gj28iyh4j2211hyynx67p3p7";
+  };
+
+  outputs = [ "out" "man" "doc" "info" "perl" ];
+
+  enableParallelBuilding = false;
+
+  patches = [
+    ./0001-Fix-cross-compilation-by-looking-for-ar.patch
+  ]
+  ++ lib.optionals (stdenv.cc.isClang && lib.versionAtLeast stdenv.cc.version "9") [
+    # https://trac.macports.org/ticket/59783
+    (fetchpatch {
+      url = "https://raw.githubusercontent.com/openembedded/openembedded-core/ce265cf467f1c3e5ba2edbfbef2170df1a727a52/meta/recipes-extended/groff/files/0001-Include-config.h.patch";
+      sha256 = "1b0mg31xkpxkzlx696nr08rcc7ndpaxdplvysy0hw5099c4n1wyf";
+    })
+  ];
+
+  postPatch = lib.optionalString (psutils != null) ''
+    substituteInPlace src/preproc/html/pre-html.cpp \
+      --replace "psselect" "${psutils}/bin/psselect"
+  '' + lib.optionalString (netpbm != null) ''
+    substituteInPlace src/preproc/html/pre-html.cpp \
+      --replace "pnmcut" "${lib.getBin netpbm}/bin/pnmcut" \
+      --replace "pnmcrop" "${lib.getBin netpbm}/bin/pnmcrop" \
+      --replace "pnmtopng" "${lib.getBin netpbm}/bin/pnmtopng"
+    substituteInPlace tmac/www.tmac \
+      --replace "pnmcrop" "${lib.getBin netpbm}/bin/pnmcrop" \
+      --replace "pngtopnm" "${lib.getBin netpbm}/bin/pngtopnm" \
+      --replace "@PNMTOPS_NOSETPAGE@" "${lib.getBin netpbm}/bin/pnmtops -nosetpage"
+  '';
+
+  buildInputs = [ ghostscript psutils netpbm perl ];
+  nativeBuildInputs = [ autoreconfHook pkg-config texinfo ];
+
+  # Builds running without a chroot environment may detect the presence
+  # of /usr/X11 in the host system, leading to an impure build of the
+  # package. To avoid this issue, X11 support is explicitly disabled.
+  # Note: If we ever want to *enable* X11 support, then we'll probably
+  # have to pass "--with-appresdir", too.
+  configureFlags = [
+    "--without-x"
+  ] ++ lib.optionals (ghostscript != null) [
+    "--with-gs=${ghostscript}/bin/gs"
+  ] ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
+    "ac_cv_path_PERL=${buildPackages.perl}/bin/perl"
+    "gl_cv_func_signbit=yes"
+  ];
+
+  makeFlags = lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
+    # Trick to get the build system find the proper 'native' groff
+    # http://www.mail-archive.com/bug-groff@gnu.org/msg01335.html
+    "GROFF_BIN_PATH=${buildPackages.groff}/bin"
+    "GROFFBIN=${buildPackages.groff}/bin/groff"
+  ];
+
+  doCheck = true;
+
+  postInstall = ''
+    for f in 'man.local' 'mdoc.local'; do
+        cat '${./site.tmac}' >>"$out/share/groff/site-tmac/$f"
+    done
+
+    moveToOutput bin/gropdf $perl
+    moveToOutput bin/pdfmom $perl
+    moveToOutput bin/roff2text $perl
+    moveToOutput bin/roff2pdf $perl
+    moveToOutput bin/roff2ps $perl
+    moveToOutput bin/roff2dvi $perl
+    moveToOutput bin/roff2ps $perl
+    moveToOutput bin/roff2html $perl
+    moveToOutput bin/glilypond $perl
+    moveToOutput bin/mmroff $perl
+    moveToOutput bin/roff2x $perl
+    moveToOutput bin/afmtodit $perl
+    moveToOutput bin/gperl $perl
+    moveToOutput bin/chem $perl
+
+    moveToOutput bin/gpinyin $perl
+    moveToOutput lib/groff/gpinyin $perl
+    substituteInPlace $perl/bin/gpinyin \
+      --replace $out/lib/groff/gpinyin $perl/lib/groff/gpinyin
+
+    moveToOutput bin/groffer $perl
+    moveToOutput lib/groff/groffer $perl
+    substituteInPlace $perl/bin/groffer \
+      --replace $out/lib/groff/groffer $perl/lib/groff/groffer
+
+    moveToOutput bin/grog $perl
+    moveToOutput lib/groff/grog $perl
+    substituteInPlace $perl/bin/grog \
+      --replace $out/lib/groff/grog $perl/lib/groff/grog
+
+  '' + lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform) ''
+    find $perl/ -type f -print0 | xargs --null sed -i 's|${buildPackages.perl}|${perl}|'
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.gnu.org/software/groff/";
+    description = "GNU Troff, a typesetting package that reads plain text and produces formatted output";
+    license = licenses.gpl3Plus;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ pSub ];
+
+    longDescription = ''
+      groff is the GNU implementation of troff, a document formatting
+      system.  Included in this release are implementations of troff,
+      pic, eqn, tbl, grn, refer, -man, -mdoc, -mom, and -ms macros,
+      and drivers for PostScript, TeX dvi format, HP LaserJet 4
+      printers, Canon CAPSL printers, HTML and XHTML format (beta
+      status), and typewriter-like devices.  Also included is a
+      modified version of the Berkeley -me macros, the enhanced
+      version gxditview of the X11 xditview previewer, and an
+      implementation of the -mm macros.
+    '';
+
+    outputsToInstall = [ "out" "perl" ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/groff/site.tmac b/nixpkgs/pkgs/tools/text/groff/site.tmac
new file mode 100644
index 000000000000..776a7abb1da7
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/groff/site.tmac
@@ -0,0 +1,19 @@
+.
+.if n \{\
+.  \" Character translations for non-keyboard
+.  \" characters - to make them searchable
+.  if '\*[.T]'utf8' \{\
+.    char \- \N'45'
+.    char - \N'45'
+.    char ' \N'39'
+.    char \' \N'39'
+.  \}
+.
+.  \" Shut off SGR by default (groff colors)
+.  \" Require GROFF_SGR envvar defined to turn it on
+.  if '\V[GROFF_SGR]'' \
+.    output x X tty: sgr 0
+.\}
+.
+.ds doc-default-operating-system Nixpkgs
+.ds doc-volume-operating-system Nixpkgs
diff --git a/nixpkgs/pkgs/tools/text/gtranslator/default.nix b/nixpkgs/pkgs/tools/text/gtranslator/default.nix
new file mode 100644
index 000000000000..5bc99724e3fa
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gtranslator/default.nix
@@ -0,0 +1,76 @@
+{ lib, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, itstool
+, gettext
+, python3
+, wrapGAppsHook
+, libxml2
+, libgda
+, libhandy
+, libsoup
+, json-glib
+, gspell
+, glib
+, libdazzle
+, gtk3
+, gtksourceview4
+, gnome
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gtranslator";
+  version = "40.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "0d48nc11z0m91scy21ah56ysxns82zvswx8lglvlkig1vqvblgpc";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    itstool
+    gettext
+    python3
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    libxml2
+    glib
+    gtk3
+    libdazzle
+    gtksourceview4
+    libgda
+    libhandy
+    libsoup
+    json-glib
+    gettext
+    gspell
+    gsettings-desktop-schemas
+  ];
+
+  postPatch = ''
+    chmod +x build-aux/meson/meson_post_install.py
+    patchShebangs build-aux/meson/meson_post_install.py
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  meta = with lib; {
+    description = "GNOME translation making program";
+    homepage = "https://wiki.gnome.org/Apps/Gtranslator";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ jtojnar ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gucci/default.nix b/nixpkgs/pkgs/tools/text/gucci/default.nix
new file mode 100644
index 000000000000..c937e6c7ab16
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gucci/default.nix
@@ -0,0 +1,29 @@
+{ lib, buildGoPackage, fetchFromGitHub }:
+
+buildGoPackage rec {
+  pname = "gucci";
+  version = "0.1.0";
+
+  goPackagePath = "github.com/noqcks/gucci";
+
+  src = fetchFromGitHub {
+    owner = "noqcks";
+    repo = "gucci";
+    rev = version;
+    sha256 = "0ksrmzb3iggc7gm51fl0jbb15d0gmpclslpkq2sl2xjzk29pkllq";
+  };
+
+  goDeps = ./deps.nix;
+
+  ldflags = [
+    "-X main.AppVersion=${version}"
+  ];
+
+  meta = with lib; {
+    description = "A simple CLI templating tool written in golang";
+    homepage = "https://github.com/noqcks/gucci";
+    license = licenses.mit;
+    maintainers = [ maintainers.braydenjw ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/gucci/deps.nix b/nixpkgs/pkgs/tools/text/gucci/deps.nix
new file mode 100644
index 000000000000..8e2cc5af3bf1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/gucci/deps.nix
@@ -0,0 +1,30 @@
+[
+  {
+    goPackagePath = "gopkg.in/yaml.v2";
+    fetch = {
+      type = "git";
+      url = "https://gopkg.in/yaml.v2";
+      rev = "5420a8b6744d3b0345ab293f6fcba19c978f1183";
+      sha256 = "0dwjrs2lp2gdlscs7bsrmyc5yf6mm4fvgw71bzr9mv2qrd2q73s1";
+    };
+  }
+  {
+    goPackagePath = "github.com/imdario/mergo";
+    fetch = {
+      type = "git";
+      url = "https://github.com/imdario/mergo";
+      rev = "v0.3.6";
+      sha256 = "1lbzy8p8wv439sqgf0n21q52flf2wbamp6qa1jkyv6an0nc952q7";
+    };
+  }
+  {
+    goPackagePath = "github.com/urfave/cli";
+    fetch = {
+      type = "git";
+      url = "https://github.com/urfave/cli";
+      rev = "v1.20.0";
+      sha256 = "0y6f4sbzkiiwrxbl15biivj8c7qwxnvm3zl2dd3mw4wzg4x10ygj";
+    };
+  }
+]
+
diff --git a/nixpkgs/pkgs/tools/text/hck/default.nix b/nixpkgs/pkgs/tools/text/hck/default.nix
new file mode 100644
index 000000000000..c17488bf67ac
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/hck/default.nix
@@ -0,0 +1,35 @@
+{ lib
+, rustPlatform
+, fetchFromGitHub
+, cmake
+, stdenv
+, libiconv
+, CoreFoundation
+, Security
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "hck";
+  version = "0.6.5";
+
+  src = fetchFromGitHub {
+    owner = "sstadick";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-+gBxZCBJmwe92DhfVorkfXsjpjkgm7JO/p/SHta9ly8=";
+  };
+
+  cargoSha256 = "sha256-lAKMaUrXjplh5YhMZuLhTNDQBzDPHCfFrELHicwgi6U=";
+
+  nativeBuildInputs = [ cmake ];
+
+  buildInputs = lib.optionals stdenv.isDarwin [ libiconv CoreFoundation Security ];
+
+  meta = with lib; {
+    description = "A close to drop in replacement for cut that can use a regex delimiter instead of a fixed string";
+    homepage = "https://github.com/sstadick/hck";
+    changelog = "https://github.com/sstadick/hck/blob/v${version}/CHANGELOG.md";
+    license = with licenses; [ mit /* or */ unlicense ];
+    maintainers = with maintainers; [ figsoda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/highlight/default.nix b/nixpkgs/pkgs/tools/text/highlight/default.nix
new file mode 100644
index 000000000000..f44ddc9d0e91
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/highlight/default.nix
@@ -0,0 +1,58 @@
+{ lib, stdenv, fetchFromGitLab, getopt, lua, boost, pkg-config, swig, perl, gcc }:
+
+with lib;
+
+let
+  self = stdenv.mkDerivation rec {
+    pname = "highlight";
+    version = "4.1";
+
+    src = fetchFromGitLab {
+      owner = "saalen";
+      repo = "highlight";
+      rev = "v${version}";
+      sha256 = "sha256-KktwbnL13Tcc2iWAjgqQSMSenUN6nYBEGbFrpB1kkr0=";
+    };
+
+    enableParallelBuilding = true;
+
+    nativeBuildInputs = [ pkg-config swig perl ] ++ optional stdenv.isDarwin gcc;
+
+    buildInputs = [ getopt lua boost ];
+
+    prePatch = lib.optionalString stdenv.cc.isClang ''
+      substituteInPlace src/makefile \
+          --replace 'CXX=g++' 'CXX=clang++'
+    '';
+
+    preConfigure = ''
+      makeFlags="PREFIX=$out conf_dir=$out/etc/highlight/ CXX=$CXX AR=$AR"
+    '';
+
+    # This has to happen _before_ the main build because it does a
+    # `make clean' for some reason.
+    preBuild = optionalString (!stdenv.isDarwin) ''
+      make -C extras/swig $makeFlags perl
+    '';
+
+    postCheck = optionalString (!stdenv.isDarwin) ''
+      perl -Iextras/swig extras/swig/testmod.pl
+    '';
+
+    preInstall = optionalString (!stdenv.isDarwin) ''
+      mkdir -p $out/${perl.libPrefix}
+      install -m644 extras/swig/highlight.{so,pm} $out/${perl.libPrefix}
+      make -C extras/swig clean # Clean up intermediate files.
+    '';
+
+    meta = with lib; {
+      description = "Source code highlighting tool";
+      homepage = "http://www.andre-simon.de/doku/highlight/en/highlight.php";
+      platforms = platforms.unix;
+      maintainers = with maintainers; [ willibutz ];
+    };
+  };
+
+in
+  if stdenv.isDarwin then self
+  else perl.pkgs.toPerlModule self
diff --git a/nixpkgs/pkgs/tools/text/hottext/default.nix b/nixpkgs/pkgs/tools/text/hottext/default.nix
new file mode 100644
index 000000000000..6fe7a686c100
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/hottext/default.nix
@@ -0,0 +1,46 @@
+{ lib, nimPackages, fetchurl, gentium, makeDesktopItem }:
+
+nimPackages.buildNimPackage rec {
+  pname = "hottext";
+  version = "1.4";
+
+  nimBinOnly = true;
+
+  src = fetchurl {
+    url = "https://git.sr.ht/~ehmry/hottext/archive/v${version}.tar.gz";
+    sha256 = "sha256-hIUofi81zowSMbt1lUsxCnVzfJGN3FEiTtN8CEFpwzY=";
+  };
+
+  buildInputs = with nimPackages; [
+    bumpy
+    chroma
+    flatty
+    nimsimd
+    pixie
+    sdl2
+    typography
+    vmath
+    zippy
+  ];
+
+  HOTTEXT_FONT_PATH = "${gentium}/share/fonts/truetype/GentiumPlus-Regular.ttf";
+
+  desktopItem = makeDesktopItem {
+    categories = "Utility;";
+    comment = meta.description;
+    desktopName = pname;
+    exec = pname;
+    name = pname;
+  };
+
+  postInstall = ''
+    cp -r $desktopItem/* $out
+  '';
+
+  meta = with lib; {
+    description = "Simple RSVP speed-reading utility";
+    license = licenses.unlicense;
+    homepage = "https://git.sr.ht/~ehmry/hottext";
+    maintainers = with maintainers; [ ehmry ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/html-tidy/default.nix b/nixpkgs/pkgs/tools/text/html-tidy/default.nix
new file mode 100644
index 000000000000..d4bb26a0a777
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/html-tidy/default.nix
@@ -0,0 +1,32 @@
+{ lib, stdenv, fetchFromGitHub, cmake, libxslt }:
+
+stdenv.mkDerivation rec {
+  pname = "html-tidy";
+  version = "5.8.0";
+
+  src = fetchFromGitHub {
+    owner = "htacg";
+    repo = "tidy-html5";
+    rev = version;
+    sha256 = "sha256-ZMz0NySxzX2XHiqB8f5asvwjIG6kdIcq8Gb3EbAxBaU=";
+  };
+
+  nativeBuildInputs = [ cmake libxslt/*manpage*/ ];
+
+  cmakeFlags = [];
+
+  # ATM bin/tidy is statically linked, as upstream provides no other option yet.
+  # https://github.com/htacg/tidy-html5/issues/326#issuecomment-160322107
+
+  meta = with lib; {
+    description = "A HTML validator and `tidier'";
+    longDescription = ''
+      HTML Tidy is a command-line tool and C library that can be
+      used to validate and fix HTML data.
+    '';
+    license = licenses.libpng; # very close to it - the 3 clauses are identical
+    homepage = "http://html-tidy.org";
+    platforms = platforms.all;
+    maintainers = with maintainers; [ edwtjo ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/html2text/default.nix b/nixpkgs/pkgs/tools/text/html2text/default.nix
new file mode 100644
index 000000000000..fff3e44baf69
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/html2text/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "html2text";
+  version = "1.3.2a";
+
+  src = fetchurl {
+    url = "http://www.mbayer.de/html2text/downloads/html2text-${version}.tar.gz";
+    sha256 = "000b39d5d910b867ff7e087177b470a1e26e2819920dcffd5991c33f6d480392";
+  };
+
+  preConfigure = ''
+    substituteInPlace configure \
+        --replace /bin/echo echo \
+        --replace CXX=unknown ':'
+  '';
+
+  # the --prefix has no effect
+  installPhase = ''
+    mkdir -p $out/bin $out/man/man{1,5}
+    cp html2text $out/bin
+    cp html2text.1.gz $out/man/man1
+    cp html2textrc.5.gz $out/man/man5
+  '';
+
+  meta = {
+    description = "Convert HTML to plain text";
+    homepage = "http://www.mbayer.de/html2text/";
+    license = lib.licenses.gpl2Plus;
+    platforms = lib.platforms.unix;
+    maintainers = [ lib.maintainers.eikek ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/hyx/default.nix b/nixpkgs/pkgs/tools/text/hyx/default.nix
new file mode 100644
index 000000000000..c287b37dd1b5
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/hyx/default.nix
@@ -0,0 +1,30 @@
+{ lib, stdenv, fetchurl, memstreamHook }:
+
+stdenv.mkDerivation rec {
+  pname = "hyx";
+  version = "2020-06-09";
+
+  src = fetchurl {
+    url = "https://yx7.cc/code/hyx/hyx-${lib.replaceStrings [ "-" ] [ "." ] version}.tar.xz";
+    sha256 = "1x8dmll93hrnj24kn5knpwj36y6r1v2ygwynpjwrg2hwd4c1a8hi";
+  };
+
+  postPatch = lib.optionalString stdenv.isDarwin ''
+    substituteInPlace Makefile \
+      --replace "-Wl,-z,relro,-z,now -fpic -pie" ""
+  '';
+
+  buildInputs = lib.optional (stdenv.system == "x86_64-darwin") memstreamHook;
+
+  installPhase = ''
+    install -vD hyx $out/bin/hyx
+  '';
+
+  meta = with lib; {
+    description = "minimalistic but powerful Linux console hex editor";
+    homepage = "https://yx7.cc/code/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fpletz ];
+    platforms = with platforms; linux ++ darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/icdiff/default.nix b/nixpkgs/pkgs/tools/text/icdiff/default.nix
new file mode 100644
index 000000000000..c051560151a9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/icdiff/default.nix
@@ -0,0 +1,34 @@
+{ lib, fetchFromGitHub, python3Packages, bash, git, less }:
+
+python3Packages.buildPythonApplication rec {
+  pname = "icdiff";
+  version = "1.9.5";
+
+  src = fetchFromGitHub {
+    owner = "jeffkaufman";
+    repo = "icdiff";
+    rev = "release-${version}";
+    sha256 = "080v8h09pv8qwplin4kwfm0kmqjwdqjfxbpcdrv16sv4hwfwl5qd";
+  };
+
+  checkInputs = [
+    bash
+    git
+    less
+  ];
+
+  # error: could not lock config file /homeless-shelter/.gitconfig: No such file or directory
+  doCheck = false;
+
+  checkPhase = ''
+    patchShebangs test.sh
+    ./test.sh ${python3Packages.python.interpreter}
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.jefftk.com/icdiff";
+    description = "Side-by-side highlighted command line diffs";
+    maintainers = with maintainers; [ aneeshusa ];
+    license = licenses.psfl;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/invoice2data/default.nix b/nixpkgs/pkgs/tools/text/invoice2data/default.nix
new file mode 100644
index 000000000000..8007724f4a53
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/invoice2data/default.nix
@@ -0,0 +1,25 @@
+{ lib, python3Packages, xpdf, imagemagick, tesseract }:
+
+python3Packages.buildPythonPackage rec {
+  pname = "invoice2data";
+  version = "0.2.93";
+
+  src = python3Packages.fetchPypi {
+    inherit pname version;
+    sha256 = "1phz0a8jxg074k0im7shrrdfvdps7bn1fa4zwcf8q3sa2iig26l4";
+  };
+
+  makeWrapperArgs = ["--prefix" "PATH" ":" (lib.makeBinPath [ imagemagick xpdf tesseract ]) ];
+
+  propagatedBuildInputs = with python3Packages; [ unidecode dateparser pyyaml pillow chardet pdfminer ];
+
+  # Tests fails even when ran manually on my ubuntu machine !!
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Data extractor for PDF invoices";
+    homepage = "https://github.com/invoice-x/invoice2data";
+    license = licenses.mit;
+    maintainers = with maintainers; [ psyanticy ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ispell/default.nix b/nixpkgs/pkgs/tools/text/ispell/default.nix
new file mode 100644
index 000000000000..9a3f37cc64a5
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ispell/default.nix
@@ -0,0 +1,38 @@
+{ lib, stdenv, fetchurl, bison, ncurses }:
+
+stdenv.mkDerivation rec {
+  pname = "ispell";
+  version = "3.4.04";
+
+  src = fetchurl {
+    url = "https://www.cs.hmc.edu/~geoff/tars/${pname}-${version}.tar.gz";
+    sha256 = "sha256-h7zW8FIdhaCjp4NCFZVtdOvEkxRMx8eR+HvmhyzP4T4=";
+  };
+
+  buildInputs = [ bison ncurses ];
+
+  postPatch = ''
+    cat >> local.h <<EOF
+    ${lib.optionalString (!stdenv.isDarwin) "#define USG"}
+    #define TERMLIB "-lncurses"
+    #define LANGUAGES "{american,MASTERDICTS=american.med,HASHFILES=americanmed.hash}"
+    #define MASTERHASH "americanmed.hash"
+    #define BINDIR "$out/bin"
+    #define LIBDIR "$out/lib"
+    #define ELISPDIR "{$out}/share/emacs/site-lisp"
+    #define TEXINFODIR "$out/share/info"
+    #define MAN1DIR "$out/share/man/man1"
+    #define MAN4DIR "$out/share/man/man4"
+    #define MAN45DIR "$out/share/man/man5"
+    #define MINIMENU
+    #define HAS_RENAME
+    EOF
+  '';
+
+  meta = with lib; {
+    description = "An interactive spell-checking program for Unix";
+    homepage = "https://www.cs.hmc.edu/~geoff/ispell.html";
+    license = licenses.free;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/jbofihe/default.nix b/nixpkgs/pkgs/tools/text/jbofihe/default.nix
new file mode 100644
index 000000000000..111b019c3b13
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/jbofihe/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchFromGitHub, bison, flex, perl, }:
+
+stdenv.mkDerivation rec {
+  pname = "jbofihe";
+  version = "0.43";
+
+  src = fetchFromGitHub {
+    owner = "lojban";
+    repo = "jbofihe";
+    rev = "v${version}";
+    sha256 = "1xx7x1256sjncyzx656jl6jl546vn8zz0siymqalz6v9yf341p98";
+  };
+
+  nativeBuildInputs = [ bison flex perl ];
+
+  doCheck = true;
+  checkPhase = ''
+    runHook preCheck
+    (cd tests && ./run *.in)
+    runHook postCheck
+  '';
+
+  meta = with lib; {
+    description = "Parser & analyser for Lojban";
+    homepage = "https://github.com/lojban/jbofihe";
+    license = licenses.gpl2Only;
+    maintainers = with maintainers; [ chkno ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/jsawk/default.nix b/nixpkgs/pkgs/tools/text/jsawk/default.nix
new file mode 100644
index 000000000000..4efaf56ccf69
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/jsawk/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchFromGitHub, makeWrapper, spidermonkey_78 }:
+
+stdenv.mkDerivation {
+  pname = "jsawk";
+  version = "1.5-pre";
+  src = fetchFromGitHub {
+    owner = "micha";
+    repo = "jsawk";
+    rev = "5a14c4af3c7b59807701b70a954ecefc6f77e978";
+    sha256 = "0z3vdr3c8nvdrrxkjv9b4xg47mdb2hsknxpimw6shgwbigihapyr";
+  };
+  dontBuild = true;
+  nativeBuildInputs = [ makeWrapper ];
+  installPhase = ''
+    mkdir -p $out/bin
+    cp $src/jsawk $out/bin/
+    wrapProgram $out/bin/jsawk \
+      --prefix PATH : "${spidermonkey_78}/bin"
+  '';
+
+  meta = {
+    description = "Like awk, but for JSON";
+    homepage = "https://github.com/micha/jsawk";
+    license = lib.licenses.publicDomain;
+    maintainers = with lib.maintainers; [ puffnfresh ];
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/jumanpp/default.nix b/nixpkgs/pkgs/tools/text/jumanpp/default.nix
new file mode 100644
index 000000000000..5fb5ec88d679
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/jumanpp/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, cmake, protobuf, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "jumanpp";
+  version = "2.0.0-rc3";
+
+  src = fetchurl {
+    url = "https://github.com/ku-nlp/${pname}/releases/download/v${version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-ASdr6qbkSe71M7QmuuwidCa4xQhDVoXBJ2XqvSY53pQ=";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ protobuf ]
+    ++ lib.optional stdenv.isDarwin libiconv;
+
+  meta = with lib; {
+    description = "A Japanese morphological analyser using a recurrent neural network language model (RNNLM)";
+    longDescription = ''
+      JUMAN++ is a new morphological analyser that considers semantic
+      plausibility of word sequences by using a recurrent neural network
+      language model (RNNLM).
+    '';
+    homepage = "https://nlp.ist.i.kyoto-u.ac.jp/index.php?JUMAN++";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ mt-caret ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/kakasi/default.nix b/nixpkgs/pkgs/tools/text/kakasi/default.nix
new file mode 100644
index 000000000000..d2cf1f701ee9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/kakasi/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchurl, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "kakasi";
+  version = "2.3.6";
+
+  buildInputs = lib.optional stdenv.isDarwin [ libiconv ];
+
+  meta = with lib; {
+    description = "Kanji Kana Simple Inverter";
+    longDescription = ''
+      KAKASI is the language processing filter to convert Kanji
+      characters to Hiragana, Katakana or Romaji and may be
+      helpful to read Japanese documents.
+    '';
+    homepage    = "http://kakasi.namazu.org/";
+    license     = licenses.gpl2Plus;
+    platforms   = platforms.unix;
+  };
+
+  src = fetchurl {
+    url = "http://kakasi.namazu.org/stable/kakasi-${version}.tar.xz";
+    sha256 = "1qry3xqb83pjgxp3my8b1sy77z4f0893h73ldrvdaky70cdppr9f";
+  };
+
+  postPatch = ''
+    for a in tests/kakasi-* ; do
+      substituteInPlace $a \
+        --replace "/bin/echo" echo
+    done
+  '';
+
+  doCheck = false; # fails 1 of 6 tests
+
+}
diff --git a/nixpkgs/pkgs/tools/text/kdiff3/default.nix b/nixpkgs/pkgs/tools/text/kdiff3/default.nix
new file mode 100644
index 000000000000..c230278c0a02
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/kdiff3/default.nix
@@ -0,0 +1,27 @@
+{
+  mkDerivation, lib, fetchurl,
+  extra-cmake-modules, kdoctools, wrapGAppsHook,
+  kcrash, kconfig, kinit, kparts, kiconthemes
+}:
+
+mkDerivation rec {
+  pname = "kdiff3";
+  version = "1.8.5";
+
+  src = fetchurl {
+    url = "https://download.kde.org/stable/${pname}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-vJL30E6xI/nFbb4wR69nv3FSQPqZSHrB0czypF4IVME=";
+  };
+
+  nativeBuildInputs = [ extra-cmake-modules kdoctools wrapGAppsHook ];
+
+  propagatedBuildInputs = [ kconfig kcrash kinit kparts kiconthemes ];
+
+  meta = with lib; {
+    homepage = "https://invent.kde.org/sdk/kdiff3";
+    license = licenses.gpl2Plus;
+    description = "Compares and merges 2 or 3 files or directories";
+    maintainers = with maintainers; [ peterhoeg ];
+    platforms = with platforms; linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/kytea/default.nix b/nixpkgs/pkgs/tools/text/kytea/default.nix
new file mode 100644
index 000000000000..9cbc2c030a45
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/kytea/default.nix
@@ -0,0 +1,32 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+
+  pname = "kytea";
+  version = "0.4.7";
+
+  src = fetchurl {
+    url    = "http://www.phontron.com/kytea/download/${pname}-${version}.tar.gz";
+    sha256 = "0ilzzwn5vpvm65bnbyb9f5rxyxy3jmbafw9w0lgl5iad1ka36jjk";
+  };
+
+  patches = [ ./gcc-O3.patch ];
+
+  NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Wno-error=c++11-narrowing";
+
+  meta = with lib; {
+    homepage = "http://www.phontron.com/kytea/";
+    description = "General toolkit developed for analyzing text";
+
+    longDescription = ''
+      A general toolkit developed for analyzing text, with a focus on Japanese,
+      Chinese and other languages requiring word or morpheme segmentation.
+    '';
+
+    license = licenses.asl20;
+
+    maintainers = with maintainers; [ ericsagnes ];
+    platforms = platforms.unix;
+  };
+
+}
diff --git a/nixpkgs/pkgs/tools/text/kytea/gcc-O3.patch b/nixpkgs/pkgs/tools/text/kytea/gcc-O3.patch
new file mode 100644
index 000000000000..71b1d0c3b16e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/kytea/gcc-O3.patch
@@ -0,0 +1,13 @@
+diff --git a/src/lib/kytea-util.cpp b/src/lib/kytea-util.cpp
+index 7c8c4c6..4492df1 100644
+--- a/src/lib/kytea-util.cpp
++++ b/src/lib/kytea-util.cpp
+@@ -49,5 +49,8 @@ void checkValueVecEqual(const std::vector<T> * a, const std::vector<T> * b) {
+ 
++template void checkValueVecEqual(const std::vector<unsigned int> & a, const std::vector<unsigned int> & b);
+ template void checkValueVecEqual(const std::vector<unsigned int> * a, const std::vector<unsigned int> * b);
++template void checkValueVecEqual(const std::vector<short> & a, const std::vector<short> & b);
+ template void checkValueVecEqual(const std::vector<short> * a, const std::vector<short> * b);
+ template void checkValueVecEqual(const std::vector<vector<KyteaString> > * a, const std::vector<vector<KyteaString> > * b);
++template void checkValueVecEqual(const std::vector<int> & a, const std::vector<int> & b);
+ template void checkValueVecEqual(const std::vector<int> * a, const std::vector<int> * b);
diff --git a/nixpkgs/pkgs/tools/text/l2md/default.nix b/nixpkgs/pkgs/tools/text/l2md/default.nix
new file mode 100644
index 000000000000..e443cc42a2ec
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/l2md/default.nix
@@ -0,0 +1,32 @@
+{ lib, stdenv, fetchgit, libgit2 }:
+
+stdenv.mkDerivation rec {
+  pname = "l2md";
+  version = "unstable-2020-07-31";
+
+  src = fetchgit {
+    url = "https://git.kernel.org/pub/scm/linux/kernel/git/dborkman/l2md.git";
+    rev = "2b9fae141fc2129940e0337732a35a3fc1c33455";
+    sha256 = "PNNoD3a+rJwKH6wbOkvVU1IW4+xF7+zQaLFAlyLlYOI=";
+  };
+
+  buildInputs = [ libgit2 ];
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp l2md $out/bin
+  '';
+
+  meta = with lib; {
+    description = "Convert public-inbox archives to maildir messages";
+    longDescription = ''
+      Quick and dirty hack to import lore.kernel.org list archives via git,
+      to export them in maildir format or through a pipe, and to keep them
+      periodically synced.
+    '';
+    homepage = "https://git.kernel.org/pub/scm/linux/kernel/git/dborkman/l2md.git";
+    license = licenses.gpl2Only;
+    maintainers = with maintainers; [ yoctocell ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/languagetool/default.nix b/nixpkgs/pkgs/tools/text/languagetool/default.nix
new file mode 100644
index 000000000000..791d779bf833
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/languagetool/default.nix
@@ -0,0 +1,38 @@
+{ lib, stdenv, fetchzip, jre, makeWrapper }:
+
+stdenv.mkDerivation rec {
+  pname = "LanguageTool";
+  version = "5.4";
+
+  src = fetchzip {
+    url = "https://www.languagetool.org/download/${pname}-${version}.zip";
+    sha256 = "sha256-2khadADfzwkW+J0uafPWJ6xUQRSQDm8seiBHueQGmKI=";
+  };
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ jre ];
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/share
+    mv -- * $out/share/
+
+    for lt in languagetool{,-commandline,-server};do
+      makeWrapper ${jre}/bin/java $out/bin/$lt \
+        --add-flags "-cp $out/share/ -jar $out/share/$lt.jar"
+    done
+
+    makeWrapper ${jre}/bin/java $out/bin/languagetool-http-server \
+      --add-flags "-cp $out/share/languagetool-server.jar org.languagetool.server.HTTPServer"
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    homepage = "https://languagetool.org";
+    license = licenses.lgpl21Plus;
+    maintainers = with maintainers; [ edwtjo ];
+    platforms = jre.meta.platforms;
+    description = "A proofreading program for English, French German, Polish, and more";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ledger2beancount/default.nix b/nixpkgs/pkgs/tools/text/ledger2beancount/default.nix
new file mode 100644
index 000000000000..caa6335d4526
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ledger2beancount/default.nix
@@ -0,0 +1,59 @@
+{ lib, stdenv, fetchFromGitHub, makeWrapper, perlPackages, beancount }:
+
+with lib;
+
+let
+  perlDeps = with perlPackages; [
+    DateCalc
+    DateTimeFormatStrptime
+    enum
+    FileBaseDir
+    GetoptLongDescriptive
+    ListMoreUtils
+    RegexpCommon
+    StringInterpolate
+    YAMLLibYAML
+  ];
+
+in stdenv.mkDerivation rec {
+  pname = "ledger2beancount";
+  version = "2.6";
+
+  src = fetchFromGitHub {
+    owner = "beancount";
+    repo = "ledger2beancount";
+    rev = version;
+    sha256 = "sha256-0Br+zuSUYrNP+ZL/FtNoaYoYBYho5kVfxu0tqKJSuBk=";
+  };
+
+  dontBuild = true;
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ perlPackages.perl beancount ] ++ perlDeps;
+
+  makeFlags = [ "prefix=$(out)" ];
+  installFlags = [ "INSTALL=install" ];
+
+  installPhase = ''
+    mkdir -p $out
+    cp -r $src/bin $out/bin
+  '';
+
+  postFixup = ''
+    wrapProgram "$out/bin/ledger2beancount" \
+      --set PERL5LIB "${perlPackages.makeFullPerlPath perlDeps}"
+  '';
+
+  meta = {
+    description = "Ledger to Beancount text-based converter";
+    longDescription = ''
+      A script to automatically convert Ledger-based textual ledgers to Beancount ones.
+
+      Conversion is based on (concrete) syntax, so that information that is not meaningful for accounting reasons but still valuable (e.g., comments, formatting, etc.) can be preserved.
+    '';
+    homepage = "https://github.com/beancount/ledger2beancount";
+    license = licenses.gpl3Plus;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ pablovsky ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/link-grammar/default.nix b/nixpkgs/pkgs/tools/text/link-grammar/default.nix
new file mode 100644
index 000000000000..3a6686dba5f2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/link-grammar/default.nix
@@ -0,0 +1,65 @@
+{ lib
+, stdenv
+, fetchurl
+, pkg-config
+, python3
+, sqlite
+, libedit
+, runCommand
+, dieHook
+}:
+
+let
+
+link-grammar = stdenv.mkDerivation rec {
+  pname = "link-grammar";
+  version = "5.9.1";
+
+  outputs = [ "bin" "out" "dev" "man" ];
+
+  src = fetchurl {
+    url = "http://www.abisource.com/downloads/${pname}/${version}/${pname}-${version}.tar.gz";
+    sha256 = "sha256-4D/rqoIGlvR+q7Az8E1xPYSQQMJMRVeRM9HQIbjssLo=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    python3
+  ];
+
+  buildInputs = [
+    sqlite
+    libedit
+  ];
+
+  configureFlags = [
+    "--disable-java-bindings"
+  ];
+
+  doCheck = true;
+
+  passthru.tests = {
+    quick = runCommand "link-grammar-quick-test" {
+      buildInputs = [
+        link-grammar
+        dieHook
+      ];
+    } ''
+      echo "Furiously sleep ideas green colorless." | link-parser en | grep "No complete linkages found." || die "Grammaticaly invalid sentence was parsed."
+      echo "Colorless green ideas sleep furiously." | link-parser en | grep "Found .* linkages." || die "Grammaticaly valid sentence was not parsed."
+      touch $out
+    '';
+  };
+
+  meta = with lib; {
+    description = "A Grammar Checking library";
+    homepage = "https://www.abisource.com/projects/link-grammar/";
+    changelog = "https://github.com/opencog/link-grammar/blob/link-grammar-${version}/ChangeLog";
+    license = licenses.lgpl21Only;
+    maintainers = with maintainers; [ jtojnar ];
+    platforms = platforms.unix;
+  };
+};
+
+in
+  link-grammar
diff --git a/nixpkgs/pkgs/tools/text/lv/default.nix b/nixpkgs/pkgs/tools/text/lv/default.nix
new file mode 100644
index 000000000000..48ed867c8e4c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/lv/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl, ncurses }:
+
+stdenv.mkDerivation rec {
+  pname = "lv";
+  version = "4.51";
+
+  src = fetchurl {
+    url = "mirror://debian/pool/main/l/${pname}/${pname}_${version}.orig.tar.gz";
+    sha256 = "0yf3idz1qspyff1if41xjpqqcaqa8q8icslqlnz0p9dj36gmm5l3";
+  };
+
+  makeFlags = [ "prefix=${placeholder "out"}" ];
+
+  buildInputs = [ ncurses ];
+
+  configurePhase = ''
+    mkdir -p build
+    cd build
+    ../src/configure
+  '';
+
+  preInstall = ''
+    mkdir -p $out/bin
+  '';
+
+  meta = with lib; {
+    description = "Powerful multi-lingual file viewer / grep";
+    homepage = "https://web.archive.org/web/20160310122517/www.ff.iij4u.or.jp/~nrt/lv/";
+    license = licenses.gpl2;
+    platforms = with platforms; linux ++ darwin;
+    maintainers = with maintainers; [ kayhide ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/m2r/default.nix b/nixpkgs/pkgs/tools/text/m2r/default.nix
new file mode 100644
index 000000000000..f6dda712d0b9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/m2r/default.nix
@@ -0,0 +1,32 @@
+{ lib
+, buildPythonApplication
+, fetchFromGitHub
+, docutils
+, mistune
+, pygments
+}:
+
+buildPythonApplication rec {
+  pname = "m2r";
+  version = "0.2.1";
+
+  src = fetchFromGitHub {
+    owner = "miyakogi";
+    repo = pname;
+    rev = "v${version}";
+    hash = "sha256-JNLPEXMoiISh4RnKP+Afj9/PJp9Lrx9UYHsfuGAL7uI=";
+  };
+
+  buildInputs = [
+    docutils
+    mistune
+    pygments
+  ];
+
+  meta = with lib; {
+    homepage = "https://github.com/miyakogi/m2r";
+    description = "Markdown-to-RestructuredText converter";
+    license = licenses.mit;
+    maintainers = with maintainers; [ AndersonTorres ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mairix/default.nix b/nixpkgs/pkgs/tools/text/mairix/default.nix
new file mode 100644
index 000000000000..aa58ecdd35a9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mairix/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchurl, zlib, bzip2, bison, flex }:
+
+stdenv.mkDerivation rec {
+  pname = "mairix";
+  version = "0.24";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/mairix/mairix-${version}.tar.gz";
+    sha256 = "0msaxz5c5hf7k1ci16i67m4ynrbrpsxbqzk84nz6z2vnkh3jww50";
+  };
+
+  buildInputs = [ zlib bzip2 bison flex ];
+
+  # https://github.com/rc0/mairix/pull/19
+  patches = [ ./mmap.patch ];
+
+  enableParallelBuilding = true;
+
+  meta = {
+    homepage = "http://www.rc0.org.uk/mairix";
+    license = lib.licenses.gpl2Plus;
+    description = "Program for indexing and searching email messages stored in maildir, MH or mbox";
+    maintainers = with lib.maintainers; [viric];
+    platforms = with lib.platforms; all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mairix/mmap.patch b/nixpkgs/pkgs/tools/text/mairix/mmap.patch
new file mode 100644
index 000000000000..241083f2dde5
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mairix/mmap.patch
@@ -0,0 +1,161 @@
+Making mairix work with mbox files over 2GB.
+
+https://github.com/rc0/mairix/pull/19
+
+diff --git a/mairix.h b/mairix.h
+index 2480492..cb25824 100644
+--- a/mairix.h
++++ b/mairix.h
+@@ -327,9 +327,9 @@ enum data_to_rfc822_error {
+   DTR8_BAD_HEADERS, /* corrupt headers */
+   DTR8_BAD_ATTACHMENT /* corrupt attachment (e.g. no body part) */
+ };
+-struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, int length, enum data_to_rfc822_error *error);
+-void create_ro_mapping(const char *filename, unsigned char **data, int *len);
+-void free_ro_mapping(unsigned char *data, int len);
++struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, size_t length, enum data_to_rfc822_error *error);
++void create_ro_mapping(const char *filename, unsigned char **data, size_t *len);
++void free_ro_mapping(unsigned char *data, size_t len);
+ char *format_msg_src(struct msg_src *src);
+ 
+ /* In tok.c */
+diff --git a/mbox.c b/mbox.c
+index ebbfa78..396e27d 100644
+--- a/mbox.c
++++ b/mbox.c
+@@ -816,7 +816,7 @@ void build_mbox_lists(struct database *db, const char *folder_base, /*{{{*/
+         mb->n_old_msgs_valid = mb->n_msgs;
+       } else {
+         unsigned char *va;
+-        int len;
++        size_t len;
+         create_ro_mapping(mb->path, &va, &len);
+         if (va) {
+           rescan_mbox(mb, (char *) va, len);
+@@ -852,7 +852,7 @@ int add_mbox_messages(struct database *db)/*{{{*/
+   int any_new = 0;
+   int N;
+   unsigned char *va;
+-  int valen;
++  size_t valen;
+   enum data_to_rfc822_error error;
+ 
+   for (i=0; i<db->n_mboxen; i++) {
+diff --git a/reader.c b/reader.c
+index 71ac5bd..18f0108 100644
+--- a/reader.c
++++ b/reader.c
+@@ -81,7 +81,8 @@ static void read_toktable2_db(char *data, struct toktable2_db *toktable, int sta
+ /*}}}*/
+ struct read_db *open_db(char *filename)/*{{{*/
+ {
+-  int fd, len;
++  int fd;
++  size_t len;
+   char *data;
+   struct stat sb;
+   struct read_db *result;
+diff --git a/reader.h b/reader.h
+index 9b5dfa3..d709cc4 100644
+--- a/reader.h
++++ b/reader.h
+@@ -138,7 +138,7 @@ struct toktable2_db {/*{{{*/
+ struct read_db {/*{{{*/
+   /* Raw file parameters, needed later for munmap */
+   char *data;
+-  int len;
++  size_t len;
+ 
+   /* Pathname information */
+   int n_msgs;
+diff --git a/rfc822.c b/rfc822.c
+index b411f85..9c8e1a4 100644
+--- a/rfc822.c
++++ b/rfc822.c
+@@ -990,7 +990,7 @@ static void scan_status_flags(const char *s, struct headers *hdrs)/*{{{*/
+ 
+ /*{{{ data_to_rfc822() */
+ struct rfc822 *data_to_rfc822(struct msg_src *src,
+-    char *data, int length,
++    char *data, size_t length,
+     enum data_to_rfc822_error *error)
+ {
+   struct rfc822 *result;
+@@ -1265,7 +1265,7 @@ static struct ro_mapping *add_ro_cache(const char *filename, int fd, size_t len)
+ }
+ #endif /* USE_GZIP_MBOX || USE_BZIP_MBOX */
+ 
+-void create_ro_mapping(const char *filename, unsigned char **data, int *len)/*{{{*/
++void create_ro_mapping(const char *filename, unsigned char **data, size_t *len)/*{{{*/
+ {
+   struct stat sb;
+   int fd;
+@@ -1386,7 +1386,7 @@ comp_error:
+   data_alloc_type = ALLOC_MMAP;
+ }
+ /*}}}*/
+-void free_ro_mapping(unsigned char *data, int len)/*{{{*/
++void free_ro_mapping(unsigned char *data, size_t len)/*{{{*/
+ {
+   int r;
+ 
+@@ -1414,7 +1414,7 @@ static struct msg_src *setup_msg_src(char *filename)/*{{{*/
+ /*}}}*/
+ struct rfc822 *make_rfc822(char *filename)/*{{{*/
+ {
+-  int len;
++  size_t len;
+   unsigned char *data;
+   struct rfc822 *result;
+ 
+diff --git a/search.c b/search.c
+index 18b51ee..97967bc 100644
+--- a/search.c
++++ b/search.c
+@@ -681,7 +681,7 @@ static void mbox_terminate(const unsigned char *data, int len, FILE *out)/*{{{*/
+ static void append_file_to_mbox(const char *path, FILE *out)/*{{{*/
+ {
+   unsigned char *data;
+-  int len;
++  size_t len;
+   create_ro_mapping(path, &data, &len);
+   if (data) {
+     fprintf(out, "From mairix@mairix Mon Jan  1 12:34:56 1970\n");
+@@ -698,8 +698,8 @@ static int had_failed_checksum;
+ 
+ static void get_validated_mbox_msg(struct read_db *db, int msg_index,/*{{{*/
+                                    int *mbox_index,
+-                                   unsigned char **mbox_data, int *mbox_len,
+-                                   unsigned char **msg_data,  int *msg_len)
++                                   unsigned char **mbox_data, size_t *mbox_len,
++                                   unsigned char **msg_data,  size_t *msg_len)
+ {
+   /* msg_data==NULL if checksum mismatches */
+   unsigned char *start;
+@@ -738,7 +738,7 @@ static void append_mboxmsg_to_mbox(struct read_db *db, int msg_index, FILE *out)
+ {
+   /* Need to common up code with try_copy_to_path */
+   unsigned char *mbox_start, *msg_start;
+-  int mbox_len, msg_len;
++  size_t mbox_len, msg_len;
+   int mbox_index;
+ 
+   get_validated_mbox_msg(db, msg_index, &mbox_index, &mbox_start, &mbox_len, &msg_start, &msg_len);
+@@ -759,7 +759,7 @@ static void append_mboxmsg_to_mbox(struct read_db *db, int msg_index, FILE *out)
+ static void try_copy_to_path(struct read_db *db, int msg_index, char *target_path)/*{{{*/
+ {
+   unsigned char *data;
+-  int mbox_len, msg_len;
++  size_t mbox_len, msg_len;
+   int mbi;
+   FILE *out;
+   unsigned char *start;
+@@ -1214,7 +1214,7 @@ static int do_search(struct read_db *db, char **args, char *output_path, int sho
+                 unsigned int mbix, msgix;
+                 int start, len, after_end;
+                 unsigned char *mbox_start, *msg_start;
+-                int mbox_len, msg_len;
++                size_t mbox_len, msg_len;
+                 int mbox_index;
+ 
+                 start = db->mtime_table[i];
diff --git a/nixpkgs/pkgs/tools/text/mark/default.nix b/nixpkgs/pkgs/tools/text/mark/default.nix
new file mode 100644
index 000000000000..b7a4537addaf
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mark/default.nix
@@ -0,0 +1,24 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "mark";
+  version = "6.3";
+
+  src = fetchFromGitHub {
+    owner  = "kovetskiy";
+    repo   = "mark";
+    rev    = version;
+    sha256 = "sha256-HKP8ZYhYDJizZ91q4MRwS00YIMvgB6EJ3au5rMg02hg=";
+  };
+
+  vendorSha256 = "sha256-y3Q8UebNbLy1jmxUC37mv+2l8dCU3b/Fk8XHn5u57p0=";
+
+  ldflags = [ "-s" "-w" "-X main.version=${version}" ];
+
+  meta = with lib; {
+    description = "A tool for syncing your markdown documentation with Atlassian Confluence pages";
+    homepage = "https://github.com/kovetskiy/mark";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ rguevara84 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/markdown-pp/default.nix b/nixpkgs/pkgs/tools/text/markdown-pp/default.nix
new file mode 100644
index 000000000000..c6e937eab275
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/markdown-pp/default.nix
@@ -0,0 +1,26 @@
+{ lib
+, fetchFromGitHub
+, python3
+}:
+
+python3.pkgs.buildPythonApplication rec {
+  pname = "MarkdownPP";
+  version = "1.5.1";
+  propagatedBuildInputs = with python3.pkgs; [ pillow watchdog ];
+  checkPhase = ''
+    cd test
+    PATH=$out/bin:$PATH ${python3}/bin/${python3.executable} test.py
+  '';
+  src = fetchFromGitHub {
+    owner = "jreese";
+    repo = "markdown-pp";
+    rev = "v${version}";
+    sha256 = "180i5wn9z6vdk2k2bh8345z3g80hj7zf5s2pq0h7k9vaxqpp7avc";
+  };
+  meta = with lib; {
+    description = "Preprocessor for Markdown files to generate a table of contents and other documentation needs";
+    license = licenses.mit;
+    homepage = "https://github.com/jreese/markdown-pp";
+    maintainers = with maintainers; [ zgrannan ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mawk/default.nix b/nixpkgs/pkgs/tools/text/mawk/default.nix
new file mode 100644
index 000000000000..62a23318ca2f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mawk/default.nix
@@ -0,0 +1,22 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "mawk";
+  version = "1.3.4-20200120";
+
+  src = fetchurl {
+    urls = [
+      "ftp://ftp.invisible-island.net/mawk/mawk-${version}.tgz"
+      "https://invisible-mirror.net/archives/mawk/mawk-${version}.tgz"
+    ];
+    sha256 = "0dw2icf8bnqd9y0clfd9pkcxz4b2phdihwci13z914mf3wgcvm3z";
+  };
+
+  meta = with lib; {
+    description = "Interpreter for the AWK Programming Language";
+    homepage = "https://invisible-island.net/mawk/mawk.html";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ ehmry ];
+    platforms = with platforms; unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mb2md/default.nix b/nixpkgs/pkgs/tools/text/mb2md/default.nix
new file mode 100644
index 000000000000..78ce7f593974
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mb2md/default.nix
@@ -0,0 +1,38 @@
+{ lib, stdenv, fetchurl, makeWrapper, perlPackages }:
+
+let
+  perlDeps = with perlPackages; [ TimeDate ];
+in
+stdenv.mkDerivation rec {
+  version = "3.20";
+  pname = "mb2md";
+
+  src = fetchurl {
+    url = "http://batleth.sapienti-sat.org/projects/mb2md/mb2md-${version}.pl.gz";
+    sha256 = "0bvkky3c90738h3skd2f1b2yy5xzhl25cbh9w2dy97rs86ssjidg";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ perlPackages.perl ];
+
+  unpackPhase = ''
+    sourceRoot=.
+    gzip -d < $src > mb2md.pl
+  '';
+
+  installPhase = ''
+    install -D $sourceRoot/mb2md.pl $out/bin/mb2md
+  '';
+
+  postFixup = ''
+    wrapProgram $out/bin/mb2md \
+      --set PERL5LIB "${perlPackages.makePerlPath perlDeps}"
+  '';
+
+  meta = with lib; {
+    description = "mbox to maildir tool";
+    license = licenses.publicDomain;
+    platforms = platforms.all;
+    maintainers = [ maintainers.jb55 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mdbook-mermaid/default.nix b/nixpkgs/pkgs/tools/text/mdbook-mermaid/default.nix
new file mode 100644
index 000000000000..741bc652e518
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mdbook-mermaid/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, CoreServices }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "mdbook-mermaid";
+  version = "0.8.3";
+
+  src = fetchFromGitHub {
+    owner = "badboy";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-maYFOlWNqKFmyDM2nDF25rzYnUXMlV9Ry9TMoXReUUg=";
+  };
+
+  cargoSha256 = "sha256-GL5Z4KfRu0zQAzVCWRIhaYtG5FrDdQabsbyFX7SjZvg=";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ CoreServices ];
+
+  meta = with lib; {
+    description = "A preprocessor for mdbook to add mermaid.js support";
+    homepage = "https://github.com/badboy/mdbook-mermaid";
+    license = [ licenses.mpl20 ];
+    maintainers = with maintainers; [ xrelkd ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mdbook/default.nix b/nixpkgs/pkgs/tools/text/mdbook/default.nix
new file mode 100644
index 000000000000..d3a136d6bf75
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mdbook/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, CoreServices }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "mdbook";
+  version = "0.4.12";
+
+  src = fetchFromGitHub {
+    owner = "rust-lang";
+    repo = "mdBook";
+    rev = "v${version}";
+    sha256 = "sha256-2lxotwL3Dc9jRA12iKO5zotO80pa+RfUZucyDRgFOsI=";
+  };
+
+  cargoSha256 = "sha256-TNd4pj4qSKgmmVtSCSKFCxNtv96xD7+24BPsLXPgiEI=";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ CoreServices ];
+
+  meta = with lib; {
+    description = "Create books from MarkDown";
+    homepage = "https://github.com/rust-lang/mdBook";
+    license = [ licenses.mpl20 ];
+    maintainers = [ maintainers.havvy ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mdcat/default.nix b/nixpkgs/pkgs/tools/text/mdcat/default.nix
new file mode 100644
index 000000000000..67f69ecc71d2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mdcat/default.nix
@@ -0,0 +1,56 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, rustPlatform
+, pkg-config
+, asciidoctor
+, openssl
+, Security
+, ansi2html
+, installShellFiles
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "mdcat";
+  version = "0.23.2";
+
+  src = fetchFromGitHub {
+    owner = "lunaryorn";
+    repo = pname;
+    rev = "mdcat-${version}";
+    sha256 = "sha256-PM6bx7qzEx4He9aX4WRO7ad/f9+wzT+gPGXKwYwG8+A=";
+  };
+
+  nativeBuildInputs = [ pkg-config asciidoctor installShellFiles ];
+  buildInputs = [ openssl ]
+    ++ lib.optional stdenv.isDarwin Security;
+
+  cargoSha256 = "sha256-GL9WGoyM1++QFAR+bzj0XkjaRaDCWcbcahles5amNpk=";
+
+  checkInputs = [ ansi2html ];
+  # Skip tests that use the network and that include files.
+  checkFlags = [
+    "--skip magic::tests::detect_mimetype_of_larger_than_magic_param_bytes_max_length"
+    "--skip magic::tests::detect_mimetype_of_magic_param_bytes_max_length"
+    "--skip magic::tests::detect_mimetype_of_png_image"
+    "--skip magic::tests::detect_mimetype_of_svg_image"
+    "--skip resources::tests::read_url_with_http_url_fails_when_size_limit_is_exceeded"
+    "--skip resources::tests::read_url_with_http_url_fails_when_status_404"
+    "--skip resources::tests::read_url_with_http_url_returns_content_when_status_200"
+    "--skip iterm2_tests_render_md_samples_images_md"
+  ];
+
+  postInstall = ''
+    installManPage $releaseDir/build/mdcat-*/out/mdcat.1
+    installShellCompletion --bash $releaseDir/build/mdcat-*/out/completions/mdcat.bash
+    installShellCompletion --fish $releaseDir/build/mdcat-*/out/completions/mdcat.fish
+    installShellCompletion --zsh $releaseDir/build/mdcat-*/out/completions/_mdcat
+  '';
+
+  meta = with lib; {
+    description = "cat for markdown";
+    homepage = "https://github.com/lunaryorn/mdcat";
+    license = with licenses; [ asl20 ];
+    maintainers = with maintainers; [ davidtwco SuperSandro2000 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mecab/base.nix b/nixpkgs/pkgs/tools/text/mecab/base.nix
new file mode 100644
index 000000000000..181eb405cbd7
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mecab/base.nix
@@ -0,0 +1,16 @@
+{ fetchurl }:
+
+{
+    version = "0.996";
+
+    src = fetchurl {
+      url = "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE";
+      name = "mecab-0.996.tar.gz";
+      sha256 = "0ncwlqxl1hdn1x4v4kr2sn1sbbcgnhdphp0lcvk74nqkhdbk4wz0";
+    };
+
+    buildPhase = ''
+      make
+      make check
+    '';
+}
diff --git a/nixpkgs/pkgs/tools/text/mecab/default.nix b/nixpkgs/pkgs/tools/text/mecab/default.nix
new file mode 100644
index 000000000000..c579dcb8a175
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mecab/default.nix
@@ -0,0 +1,20 @@
+{ lib, stdenv, fetchurl, mecab-ipadic }:
+
+let
+  mecab-base = import ./base.nix { inherit fetchurl; };
+in
+stdenv.mkDerivation (mecab-base // {
+    name = "mecab-${mecab-base.version}";
+
+    postInstall = ''
+      sed -i 's|^dicdir = .*$|dicdir = ${mecab-ipadic}|' "$out/etc/mecabrc"
+    '';
+
+    meta = with lib; {
+      description = "Japanese morphological analysis system";
+      homepage = "http://taku910.github.io/mecab/";
+      license = licenses.bsd3;
+      platforms = platforms.unix;
+      maintainers = with maintainers; [ auntie ];
+    };
+})
diff --git a/nixpkgs/pkgs/tools/text/mecab/ipadic.nix b/nixpkgs/pkgs/tools/text/mecab/ipadic.nix
new file mode 100644
index 000000000000..026e385e7c2b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mecab/ipadic.nix
@@ -0,0 +1,18 @@
+{ stdenv, fetchurl, mecab-nodic }:
+
+stdenv.mkDerivation {
+  pname = "mecab-ipadic";
+  version = "2.7.0-20070801";
+
+  src = fetchurl {
+    url = "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM";
+    name = "mecab-ipadic-2.7.0-20070801.tar.gz";
+    sha256 = "08rmkvj0f0x6jq0axrjw2y5nam0mavv6x77dp9v4al0wi1ym4bxn";
+  };
+
+  buildInputs = [ mecab-nodic ];
+
+  configurePhase = ''
+    ./configure --with-dicdir="$out"
+  '';
+}
diff --git a/nixpkgs/pkgs/tools/text/mecab/nodic.nix b/nixpkgs/pkgs/tools/text/mecab/nodic.nix
new file mode 100644
index 000000000000..1cbc31be4ee1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mecab/nodic.nix
@@ -0,0 +1,8 @@
+{ stdenv, fetchurl }:
+
+let
+  mecab-base = import ./base.nix { inherit fetchurl; };
+in
+stdenv.mkDerivation (mecab-base // {
+    name = "mecab-nodic-${mecab-base.version}";
+})
diff --git a/nixpkgs/pkgs/tools/text/miller/default.nix b/nixpkgs/pkgs/tools/text/miller/default.nix
new file mode 100644
index 000000000000..670c0612b391
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/miller/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, autoreconfHook, flex, libtool }:
+
+stdenv.mkDerivation rec {
+  pname = "miller";
+
+  version = "5.10.2";
+
+  src = fetchFromGitHub {
+    owner = "johnkerl";
+    repo = "miller";
+    rev = "v${version}";
+    sha256 = "sha256-NI57U3FpUfQ6ouBEYrzzG+9kpL58BD4HoAuRAFJMO9k=";
+  };
+
+  nativeBuildInputs = [ autoreconfHook flex libtool ];
+
+  meta = with lib; {
+    description = "Like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON";
+    homepage    = "http://johnkerl.org/miller/";
+    license     = licenses.bsd2;
+    maintainers = with maintainers; [ mstarzyk ];
+    platforms   = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mir-qualia/default.nix b/nixpkgs/pkgs/tools/text/mir-qualia/default.nix
new file mode 100644
index 000000000000..f532daf8c442
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mir-qualia/default.nix
@@ -0,0 +1,21 @@
+{ lib, pythonPackages, fetchurl }:
+
+pythonPackages.buildPythonApplication rec {
+  pname = "mir.qualia";
+  version = "2.0.0";
+  doCheck = false; # 2.0.0-released pytests are broken
+
+  buildInputs = with pythonPackages; [ pytest ];
+
+  src = fetchurl {
+    url = "mirror://pypi/m/mir.qualia/mir.qualia-${version}.tar.gz";
+    sha256 = "1ybq6jb5clh9hw0sp3idp4hjv2gkm9yiaph48gcc208affflc8m9";
+  };
+
+  meta = {
+    description = "Dynamically enable sections of config files";
+    homepage = "https://github.com/darkfeline/mir.qualia";
+    license = lib.licenses.asl20;
+    maintainers = [ lib.maintainers.srhb ] ;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/mpage/default.nix b/nixpkgs/pkgs/tools/text/mpage/default.nix
new file mode 100644
index 000000000000..b48f89d66180
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/mpage/default.nix
@@ -0,0 +1,32 @@
+{ fetchurl, lib, stdenv }:
+
+stdenv.mkDerivation rec {
+  pname = "mpage";
+  version = "2.5.7";
+
+  src = fetchurl {
+    url = "https://www.mesa.nl/pub/mpage/mpage-${version}.tgz";
+    sha256 = "1zn37r5xrvjgjbw2bdkc0r7s6q8b1krmcryzj0yf0dyxbx79rasi";
+  };
+
+  postPatch = ''
+    sed -i "Makefile" -e "s|^ *PREFIX *=.*$|PREFIX = $out|g"
+    substituteInPlace Makefile --replace 'gcc' '${stdenv.cc.targetPrefix}cc'
+  '';
+
+  meta = {
+    description = "Many-to-one page printing utility";
+
+    longDescription = ''
+      Mpage reads plain text files or PostScript documents and prints
+      them on a PostScript printer with the text reduced in size so
+      that several pages appear on one sheet of paper.  This is useful
+      for viewing large printouts on a small amount of paper.  It uses
+      ISO 8859.1 to print 8-bit characters.
+    '';
+
+    license = "liberal";  # a non-copyleft license, see `Copyright' file
+    homepage = "http://www.mesa.nl/pub/mpage/";
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/data/default.nix b/nixpkgs/pkgs/tools/text/multitran/data/default.nix
new file mode 100644
index 000000000000..bfc148df782b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/data/default.nix
@@ -0,0 +1,27 @@
+{lib, stdenv, fetchurl} :
+
+# This package requires a locale ru_RU.cp1251 locale entry.
+# Waiting for a better idea, I created it modifying a store file using:
+#   localedef -f CP1251 -i ru_RU ru_RU.CP1251
+# The store file mentioned is in "${glibc.out}/lib/locale/locale-archive"
+
+stdenv.mkDerivation {
+  pname = "multitran-data";
+  version = "0.3";
+
+  src = fetchurl {
+      url = "mirror://sourceforge/multitran/multitran-data.tar.bz2";
+      sha256 = "9c2ff5027c2fe72b0cdf056311cd7543f447feb02b455982f20d4a3966b7828c";
+  };
+
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' Makefile
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran data english-russian";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/libbtree/default.nix b/nixpkgs/pkgs/tools/text/multitran/libbtree/default.nix
new file mode 100644
index 000000000000..91c4bb0ea7f8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/libbtree/default.nix
@@ -0,0 +1,21 @@
+{lib, stdenv, fetchurl} :
+
+stdenv.mkDerivation rec {
+  pname = "libbtree";
+  version = "0.0.1alpha2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/multitran/libbtree-${version}.tar.bz2";
+    sha256 = "34a584e45058950337ff9342693b6739b52c3ce17e66440526c4bd6f9575802c";
+  };
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' src/Makefile;
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran lib: library for reading Multitran's BTREE database format";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/libfacet/default.nix b/nixpkgs/pkgs/tools/text/multitran/libfacet/default.nix
new file mode 100644
index 000000000000..0e6dd0d6e652
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/libfacet/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchurl, libmtsupport }:
+
+stdenv.mkDerivation rec {
+  pname = "libfacet";
+  version = "0.0.1alpha2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/multitran/libfacet-${version}.tar.bz2";
+    sha256 = "dc53351c4035a3c27dc6c1d0410e808346fbc107e7e7c112ec65c59d0df7a144";
+  };
+
+  buildInputs = [ libmtsupport ];
+
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' \
+      -e 's@/usr/include/mt/support@${libmtsupport}/include/mt/support@' \
+      src/Makefile;
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran lib: enchanced locale facets";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/libmtquery/default.nix b/nixpkgs/pkgs/tools/text/multitran/libmtquery/default.nix
new file mode 100644
index 000000000000..5cc8e724e71f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/libmtquery/default.nix
@@ -0,0 +1,31 @@
+{lib, stdenv, fetchurl, libmtsupport, libfacet, libbtree, multitrandata } :
+
+stdenv.mkDerivation rec {
+  pname = "libmtquery";
+  version = "0.0.1alpha3";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/multitran/libmtquery-${version}.tar.bz2";
+    sha256 = "e24c7c15772445f1b14871928d84dd03cf93bd88f9d2b2ed1bf0257c2cf2b15e";
+  };
+
+  buildInputs = [ libmtsupport libfacet libbtree multitrandata ];
+
+  NIX_LDFLAGS = "-lbtree";
+
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' \
+      -e 's@/usr/include/mt/support@${libmtsupport}/include/mt/support@' \
+      -e 's@/usr/include/btree@${libbtree}/include/btree@' \
+      -e 's@/usr/include/facet@${libfacet}/include/facet@' \
+      src/Makefile testsuite/Makefile;
+    sed -i -e 's@/usr/share/multitran@${multitrandata}/share/multitran@' src/config.cc
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran lib: main engine to query translations";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/libmtsupport/default.nix b/nixpkgs/pkgs/tools/text/multitran/libmtsupport/default.nix
new file mode 100644
index 000000000000..454709b8eb79
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/libmtsupport/default.nix
@@ -0,0 +1,21 @@
+{lib, stdenv, fetchurl} :
+
+stdenv.mkDerivation rec {
+  pname = "libmtsupport";
+  version = "0.0.1alpha2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/multitran/libmtsupport-${version}.tar.bz2";
+    sha256 = "481f0f1ec15d7274f1e4eb93e7d060df10a181efd037eeff5e8056d283a9298b";
+  };
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' src/Makefile;
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran lib: basic useful functions";
+    license = lib.licenses.gpl2;
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/multitran/mtutils/default.nix b/nixpkgs/pkgs/tools/text/multitran/mtutils/default.nix
new file mode 100644
index 000000000000..2428caada5b8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/multitran/mtutils/default.nix
@@ -0,0 +1,34 @@
+{lib, stdenv, fetchurl, libmtsupport, libfacet, libbtree, libmtquery, help2man} :
+
+stdenv.mkDerivation rec {
+  pname = "mt-utils";
+  version = "0.0.1alpha3";
+
+  src = fetchurl {
+      url = "mirror://sourceforge/multitran/mt-utils-${version}.tar.bz2";
+      sha256 = "e407702c90c5272882386914e1eeca5f6c5039393af9a44538536b94867b0a0e";
+  };
+
+  buildInputs = [ libmtsupport libfacet libbtree libmtquery help2man ];
+
+  patchPhase = ''
+    sed -i -e 's@\$(DESTDIR)/usr@'$out'@' \
+      -e 's@/usr/include/mt/support@${libmtsupport}/include/mt/support@' \
+      -e 's@/usr/include/btree@${libbtree}/include/btree@' \
+      -e 's@/usr/include/facet@${libfacet}/include/facet@' \
+      -e 's@/usr/include/mt/query@${libmtquery}/include/mt/query@' \
+      -e 's@-lmtquery@-lmtquery -lmtsupport -lfacet@' \
+      src/Makefile;
+    # Fixing multibyte locale output
+    sed -i -e 's@message.length()@message.length()*5@' \
+      src/converter.cc;
+  '';
+
+  meta = {
+    homepage = "http://multitran.sourceforge.net/";
+    description = "Multitran: simple command line utilities for dictionary maintenance";
+    license = lib.licenses.gpl2;
+    maintainers = with lib.maintainers; [viric];
+    platforms = with lib.platforms; linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/namazu/default.nix b/nixpkgs/pkgs/tools/text/namazu/default.nix
new file mode 100644
index 000000000000..e748515b0513
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/namazu/default.nix
@@ -0,0 +1,34 @@
+{ fetchurl, lib, stdenv, perl, perlPackages, makeWrapper }:
+
+stdenv.mkDerivation rec {
+  pname = "namazu";
+  version = "2.0.21";
+
+  src = fetchurl {
+    url = "http://namazu.org/stable/${pname}-${version}.tar.gz";
+    sha256 = "1xvi7hrprdchdpzhg3fvk4yifaakzgydza5c0m50h1yvg6vay62w";
+  };
+
+  buildInputs = [ perl perlPackages.FileMMagic ];
+  nativeBuildInputs = [ makeWrapper ];
+
+  postInstall = ''
+    wrapProgram $out/bin/mknmz --set PERL5LIB ${perlPackages.makeFullPerlPath [ perlPackages.FileMMagic ]}
+  '';
+
+  meta = {
+    description = "Full-text search engine";
+
+    longDescription = ''
+      Namazu is a full-text search engine intended for easy use.  Not
+      only does it work as a small or medium scale Web search engine,
+      but also as a personal search system for email or other files.
+    '';
+
+    license = lib.licenses.gpl2Plus;
+    homepage = "http://namazu.org/";
+
+    platforms = lib.platforms.gnu ++ lib.platforms.linux;  # arbitrary choice
+    maintainers = [ ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/nawk/default.nix b/nixpkgs/pkgs/tools/text/nawk/default.nix
new file mode 100644
index 000000000000..580d30a58330
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/nawk/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, fetchFromGitHub, bison, buildPackages }:
+
+stdenv.mkDerivation rec {
+  pname = "nawk";
+  version = "unstable-2021-02-15";
+
+  src = fetchFromGitHub {
+    owner = "onetrueawk";
+    repo = "awk";
+    rev = "c0f4e97e4561ff42544e92512bbaf3d7d1f6a671";
+    sha256 = "kQCvItpSJnDJMDvlB8ruY+i0KdjmAphRDqCKw8f0m/8=";
+  };
+
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ bison ];
+  makeFlags = [
+    "CC=${stdenv.cc.targetPrefix}cc"
+    "HOSTCC=${if stdenv.buildPlatform.isDarwin then "clang" else "cc"}"
+  ];
+
+  installPhase = ''
+    runHook preInstall
+    install -Dm755 a.out "$out/bin/nawk"
+    install -Dm644 awk.1 "$out/share/man/man1/nawk.1"
+    runHook postInstall
+  '';
+
+  meta = {
+    description = "The one, true implementation of AWK";
+    longDescription = ''
+       This is the version of awk described in "The AWK Programming
+       Language", by Al Aho, Brian Kernighan, and Peter Weinberger
+       (Addison-Wesley, 1988, ISBN 0-201-07981-X).
+    '';
+    homepage = "https://www.cs.princeton.edu/~bwk/btl.mirror/";
+    license = lib.licenses.mit;
+    maintainers = [ lib.maintainers.konimex ];
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/nkf/default.nix b/nixpkgs/pkgs/tools/text/nkf/default.nix
new file mode 100644
index 000000000000..a2b5f66a6e91
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/nkf/default.nix
@@ -0,0 +1,21 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "nkf";
+  version = "2.1.5";
+
+  src = fetchurl {
+    url = "mirror://osdn/nkf/70406/${pname}-${version}.tar.gz";
+    sha256 = "0i5dbcb9aipwr8ym4mhvgf1in3frl6y8h8x96cprz9s7b11xz9yi";
+  };
+
+  makeFlags = [ "prefix=$(out)" ];
+
+  meta = {
+    description = "Tool for converting encoding of Japanese text";
+    homepage = "https://nkf.osdn.jp/";
+    license = lib.licenses.zlib;
+    platforms = lib.platforms.unix;
+    maintainers = [ lib.maintainers.auntie ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/num-utils/default.nix b/nixpkgs/pkgs/tools/text/num-utils/default.nix
new file mode 100644
index 000000000000..14784a4e8cfc
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/num-utils/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchurl, perl }:
+
+stdenv.mkDerivation rec {
+  pname = "num-utils";
+  version = "0.5";
+
+  src = fetchurl {
+    url = "https://suso.suso.org/programs/num-utils/downloads/num-utils-${version}.tar.gz";
+    sha256 = "0kn6yskjww2agcqvas5l2xp55mp4njdxqkdicchlji3qzih2fn83";
+  };
+
+  buildInputs = [ perl ];
+
+  patchPhase = ''
+    substituteInPlace Makefile --replace "-o 0 -g 0" "" --replace "\$(RPMDIR)" ""
+  '';
+  makeFlags = [
+    "TOPDIR=${placeholder "out"}"
+    "PERL=${perl}/bin/perl"
+  ];
+
+  meta = with lib; {
+    description = "Programs for dealing with numbers from the command line";
+    homepage = "https://suso.suso.org/xulu/Num-utils";
+    license = licenses.gpl2Plus;
+    platforms = platforms.all;
+    maintainers = [ maintainers.catern ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/numdiff/default.nix b/nixpkgs/pkgs/tools/text/numdiff/default.nix
new file mode 100644
index 000000000000..317d29003cd3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/numdiff/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchurl, libintl }:
+
+
+stdenv.mkDerivation rec {
+  pname = "numdiff";
+  version = "5.9.0";
+
+  src = fetchurl {
+    url = "mirror://savannah/numdiff/numdiff-${version}.tar.gz";
+    sha256 = "1vzmjh8mhwwysn4x4m2vif7q2k8i19x8azq7pzmkwwj4g48lla47";
+  };
+
+  buildInputs = [ libintl ];
+
+  meta = with lib; {
+    description = ''
+      A little program that can be used to compare putatively similar files
+      line by line and field by field, ignoring small numeric differences
+      or/and different numeric formats
+    '';
+    homepage = "https://www.nongnu.org/numdiff/";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/odt2txt/default.nix b/nixpkgs/pkgs/tools/text/odt2txt/default.nix
new file mode 100644
index 000000000000..0eb18e8435d4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/odt2txt/default.nix
@@ -0,0 +1,23 @@
+{ lib, stdenv, fetchurl, zlib, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "odt2txt";
+  version = "0.5";
+
+  src = fetchurl {
+    url = "${meta.homepage}/archive/v${version}.tar.gz";
+    sha256 = "23a889109ca9087a719c638758f14cc3b867a5dcf30a6c90bf6a0985073556dd";
+  };
+
+  configurePhase="export makeFlags=\"DESTDIR=$out\"";
+
+  buildInputs = [ zlib libiconv ];
+
+  meta = {
+    description = "Simple .odt to .txt converter";
+    homepage = "https://github.com/dstosberg/odt2txt";
+    platforms = lib.platforms.all;
+    license = lib.licenses.gpl2;
+    maintainers = [ ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/opencc/default.nix b/nixpkgs/pkgs/tools/text/opencc/default.nix
new file mode 100644
index 000000000000..f99062de4131
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/opencc/default.nix
@@ -0,0 +1,36 @@
+{ lib, stdenv, fetchFromGitHub, cmake, python }:
+
+stdenv.mkDerivation rec {
+  pname = "opencc";
+  version = "1.1.2";
+
+  src = fetchFromGitHub {
+    owner = "BYVoid";
+    repo = "OpenCC";
+    rev = "ver.${version}";
+    sha256 = "1a15p9idznh23b44r7rw2zjnirbxjs5pyq3k6xkz0k64cdh2zq6h";
+  };
+
+  nativeBuildInputs = [ cmake python ];
+
+  # let intermediate tools find intermediate library
+  preBuild = lib.optionalString stdenv.isLinux ''
+    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}$(pwd)/src
+  '' + lib.optionalString stdenv.isDarwin ''
+    export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH''${DYLD_LIBRARY_PATH:+:}$(pwd)/src
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/BYVoid/OpenCC";
+    license = licenses.asl20;
+    description = "A project for conversion between Traditional and Simplified Chinese";
+    longDescription = ''
+      Open Chinese Convert (OpenCC) is an opensource project for conversion between
+      Traditional Chinese and Simplified Chinese, supporting character-level conversion,
+      phrase-level conversion, variant conversion and regional idioms among Mainland China,
+      Taiwan and Hong kong.
+    '';
+    maintainers = with maintainers; [ sifmelcara ];
+    platforms = with platforms; linux ++ darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/papertrail/Gemfile b/nixpkgs/pkgs/tools/text/papertrail/Gemfile
new file mode 100755
index 000000000000..199cd1422aaa
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/papertrail/Gemfile
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+source "https://rubygems.org"
+
+gem "papertrail"
diff --git a/nixpkgs/pkgs/tools/text/papertrail/Gemfile.lock b/nixpkgs/pkgs/tools/text/papertrail/Gemfile.lock
new file mode 100644
index 000000000000..37cd23eab6f5
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/papertrail/Gemfile.lock
@@ -0,0 +1,17 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    ansi (1.5.0)
+    chronic (0.10.2)
+    papertrail (0.10.1)
+      ansi (~> 1.5)
+      chronic (~> 0.10)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  papertrail
+
+BUNDLED WITH
+   2.1.4
diff --git a/nixpkgs/pkgs/tools/text/papertrail/default.nix b/nixpkgs/pkgs/tools/text/papertrail/default.nix
new file mode 100644
index 000000000000..c3d005a97e08
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/papertrail/default.nix
@@ -0,0 +1,30 @@
+{ lib, stdenv, bundlerEnv, ruby, bundlerUpdateScript }:
+
+let
+  papertrail-env = bundlerEnv {
+    name = "papertrail-env";
+    inherit ruby;
+    gemfile = ./Gemfile;
+    lockfile = ./Gemfile.lock;
+    gemset = ./gemset.nix;
+  };
+in stdenv.mkDerivation {
+  name = "papertrail-${(import ./gemset.nix).papertrail.version}";
+
+  dontUnpack = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    ln -s ${papertrail-env}/bin/papertrail $out/bin/papertrail
+  '';
+
+  passthru.updateScript = bundlerUpdateScript "papertrail";
+
+  meta = with lib; {
+    description = "Command-line client for Papertrail log management service";
+    homepage    = "https://github.com/papertrail/papertrail-cli/";
+    license     = licenses.mit;
+    maintainers = with maintainers; [ nicknovitski ];
+    platforms   = ruby.meta.platforms;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/papertrail/gemset.nix b/nixpkgs/pkgs/tools/text/papertrail/gemset.nix
new file mode 100644
index 000000000000..dcdfcdf7ea58
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/papertrail/gemset.nix
@@ -0,0 +1,26 @@
+{
+  ansi = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "14ims9zfal4gs2wpx2m5rd8zsrl2k794d359shkrsgg3fhr2a22l";
+      type = "gem";
+    };
+    version = "1.5.0";
+  };
+  chronic = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1hrdkn4g8x7dlzxwb1rfgr8kw3bp4ywg5l4y4i9c2g5cwv62yvvn";
+      type = "gem";
+    };
+    version = "0.10.2";
+  };
+  papertrail = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0vb7bh7qh5hr4v3w711bl0yrr3rlhz5c3h3qx3fq31dr5y4100v7";
+      type = "gem";
+    };
+    version = "0.10.1";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/par/default.nix b/nixpkgs/pkgs/tools/text/par/default.nix
new file mode 100644
index 000000000000..e4c6c5d0c086
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/par/default.nix
@@ -0,0 +1,42 @@
+{lib, stdenv, fetchurl, fetchpatch}:
+
+stdenv.mkDerivation {
+  pname = "par";
+  version = "1.52";
+
+  src = fetchurl {
+    url = "http://www.nicemice.net/par/Par152.tar.gz";
+    sha256 = "33dcdae905f4b4267b4dc1f3efb032d79705ca8d2122e17efdecfd8162067082";
+  };
+
+  patches = [
+    # A patch by Jérôme Pouiller that adds support for multibyte
+    # charsets (like UTF-8), plus Debian packaging.
+    (fetchpatch {
+      url = "http://sysmic.org/dl/par/par-1.52-i18n.4.patch";
+      sha256 = "0alw44lf511jmr38jnh4j0mpp7vclgy0grkxzqf7q158vzdb6g23";
+    })
+  ];
+
+  makefile = "protoMakefile";
+  preBuild = ''
+    makeFlagsArray+=(CC="${stdenv.cc.targetPrefix}cc -c" LINK1=${stdenv.cc.targetPrefix}cc)
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp par $out/bin
+
+    mkdir -p $out/share/man/man1
+    cp  par.1 $out/share/man/man1
+  '';
+
+
+  meta = with lib; {
+    homepage = "http://www.nicemice.net/par/";
+    description = "Paragraph reflow for email";
+    platforms = platforms.unix;
+    # See https://fedoraproject.org/wiki/Licensing/Par for license details
+    license = licenses.free;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/patchutils/0.3.3.nix b/nixpkgs/pkgs/tools/text/patchutils/0.3.3.nix
new file mode 100644
index 000000000000..f50354199c3f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/patchutils/0.3.3.nix
@@ -0,0 +1,7 @@
+{ callPackage, ... } @ args:
+
+callPackage ./generic.nix (args // {
+  version = "0.3.3";
+  sha256 = "0g5df00cj4nczrmr4k791l7la0sq2wnf8rn981fsrz1f3d2yix4i";
+  patches = [ ./drop-comments.patch ]; # we would get into a cycle when using fetchpatch on this one
+})
diff --git a/nixpkgs/pkgs/tools/text/patchutils/default.nix b/nixpkgs/pkgs/tools/text/patchutils/default.nix
new file mode 100644
index 000000000000..902773f40fa4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/patchutils/default.nix
@@ -0,0 +1,6 @@
+{ callPackage, ... } @ args:
+
+callPackage ./generic.nix (args // {
+  version = "0.3.4";
+  sha256 = "0xp8mcfyi5nmb5a2zi5ibmyshxkb1zv1dgmnyn413m7ahgdx8mfg";
+})
diff --git a/nixpkgs/pkgs/tools/text/patchutils/drop-comments.patch b/nixpkgs/pkgs/tools/text/patchutils/drop-comments.patch
new file mode 100644
index 000000000000..e02693a5683d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/patchutils/drop-comments.patch
@@ -0,0 +1,84 @@
+From 58987954647f51dc42fb13b7759923c6170dd905 Mon Sep 17 00:00:00 2001
+From: Tim Waugh <twaugh@redhat.com>
+Date: Fri, 9 May 2014 16:23:27 +0100
+Subject: Make --clean drop comments after '@@' lines as well (trac #29).
+
+
+diff --git a/Makefile.am b/Makefile.am
+index 99ad2a3..f3c6dbc 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -198,6 +198,7 @@ TESTS = tests/newline1/run-test \
+ 	tests/convert1/run-test \
+ 	tests/convert2/run-test \
+ 	tests/clean1/run-test \
++	tests/clean2/run-test \
+ 	tests/stdin/run-test
+ 
+ # These ones don't work yet.
+diff --git a/src/filterdiff.c b/src/filterdiff.c
+index 383e72b..6ca2316 100644
+--- a/src/filterdiff.c
++++ b/src/filterdiff.c
+@@ -2,7 +2,7 @@
+  * filterdiff - extract (or exclude) a diff from a diff file
+  * lsdiff - show which files are modified by a patch
+  * grepdiff - show files modified by a patch containing a regexp
+- * Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009, 2011 Tim Waugh <twaugh@redhat.com>
++ * Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009, 2011, 2013, 2014 Tim Waugh <twaugh@redhat.com>
+  *
+  * 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
+@@ -408,7 +408,8 @@ do_unified (FILE *f, char *header[2], int match, char **line,
+ 							 " Hunk #%lu, %s",
+ 							 hunknum, bestname);
+ 
+-					fputs (trailing, output_to);
++					fputs (clean_comments ? "\n" : trailing,
++					       output_to);
+ 					break;
+ 				case Before:
+ 					// Note the initial line number
+diff --git a/tests/clean2/run-test b/tests/clean2/run-test
+new file mode 100755
+index 0000000..42320df
+--- /dev/null
++++ b/tests/clean2/run-test
+@@ -0,0 +1,34 @@
++#!/bin/sh
++
++# This is a filterdiff(1) testcase.
++# Test: Make sure --clean removes hunk-level comments.
++
++
++. ${top_srcdir-.}/tests/common.sh
++
++cat << EOF > diff
++non-diff line
++--- a/file1
+++++ b/file1
++@@ -0,0 +1 @@ this is a hunk-level comment
+++a
++EOF
++
++${FILTERDIFF} --clean diff 2>errors >filtered || exit 1
++[ -s errors ] && exit 1
++
++cat << EOF | cmp - filtered || exit 1
++--- a/file1
+++++ b/file1
++@@ -0,0 +1 @@
+++a
++EOF
++
++${FILTERDIFF} --clean -x file1 diff 2>errors >filtered || exit 1
++[ -s errors ] && exit 1
++cat << EOF | cmp - filtered || exit 1
++--- a/file1
+++++ b/file1
++@@ -0,0 +1 @@
+++a
++EOF
+-- 
+cgit v0.10.1
+
diff --git a/nixpkgs/pkgs/tools/text/patchutils/generic.nix b/nixpkgs/pkgs/tools/text/patchutils/generic.nix
new file mode 100644
index 000000000000..d3e9da242e2e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/patchutils/generic.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, perl
+, version, sha256, patches ? []
+, ...
+}:
+stdenv.mkDerivation rec {
+  pname = "patchutils";
+  inherit version patches;
+
+  src = fetchurl {
+    url = "http://cyberelk.net/tim/data/patchutils/stable/${pname}-${version}.tar.xz";
+    inherit sha256;
+  };
+
+  buildInputs = [ perl ];
+  hardeningDisable = [ "format" ];
+
+  doCheck = false; # fails
+
+  meta = with lib; {
+    description = "Tools to manipulate patch files";
+    homepage = "http://cyberelk.net/tim/software/patchutils";
+    license = licenses.gpl2Plus;
+    platforms = platforms.all;
+    executables = [ "combinediff" "dehtmldiff" "editdiff" "espdiff"
+      "filterdiff" "fixcvsdiff" "flipdiff" "grepdiff" "interdiff" "lsdiff"
+      "recountdiff" "rediff" "splitdiff" "unwrapdiff" ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/pbgopy/default.nix b/nixpkgs/pkgs/tools/text/pbgopy/default.nix
new file mode 100644
index 000000000000..d4ed4eb0f03a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/pbgopy/default.nix
@@ -0,0 +1,22 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "pbgopy";
+  version = "0.3.0";
+
+  src = fetchFromGitHub {
+    owner = "nakabonne";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-P/MFDFMsqSTVErTM9izJJSMIbiOcbQ9Ya10/w6NRcYw=";
+  };
+
+  vendorSha256 = "sha256-S2X74My6wyDZOsEYTDilCFaYgV2vQzU0jOAY9cEkJ6A=";
+
+  meta = with lib; {
+    description = "Copy and paste between devices";
+    homepage = "https://github.com/nakabonne/pbgopy";
+    license = licenses.mit;
+    maintainers = [ maintainers.ivar ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/peco/default.nix b/nixpkgs/pkgs/tools/text/peco/default.nix
new file mode 100644
index 000000000000..36951be7edbc
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/peco/default.nix
@@ -0,0 +1,25 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "peco";
+  version = "0.5.10";
+
+  subPackages = [ "cmd/peco" ];
+
+  src = fetchFromGitHub {
+    owner = "peco";
+    repo = "peco";
+    rev = "v${version}";
+    sha256 = "sha256-Iu2MclUbUYX1FuMnE65Qdk0S+5+K3HW86WIdQrNUyY8=";
+  };
+
+  vendorSha256 = "sha256-+HQz7UUgATdgSWlI1dg2DdQRUSke9MyAtXgLikFhF90=";
+
+  meta = with lib; {
+    description = "Simplistic interactive filtering tool";
+    homepage = "https://github.com/peco/peco";
+    changelog = "https://github.com/peco/peco/blob/v${version}/Changes";
+    license = licenses.mit;
+    maintainers = with maintainers; [ pSub ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/pinyin-tool/default.nix b/nixpkgs/pkgs/tools/text/pinyin-tool/default.nix
new file mode 100644
index 000000000000..9d98385933b1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/pinyin-tool/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, lib, rustPlatform, fetchFromGitHub, Security }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "pinyin-tool";
+  version = "0.1.3";
+
+  src = fetchFromGitHub {
+    owner = "briankung";
+    repo = pname;
+    rev = version;
+    sha256 = "1gwqwxlvdrm4sdyqkvpvvfi6jh6qqn6qybn0z66wm06k62f8zj5b";
+  };
+
+  cargoSha256 = "1ixl4bsb8c8dmz9s28a2v5l5f2hi3g9xjy6ribmhybpwmfs4mr4d";
+
+  buildInputs = lib.optionals stdenv.isDarwin [ Security ];
+
+  meta = with lib; {
+    description = "A simple command line tool for converting Chinese characters to space-separate pinyin words";
+    homepage = "https://github.com/briankung/pinyin-tool";
+    license = licenses.mit;
+    maintainers = with maintainers; [ neonfuz ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/platinum-searcher/default.nix b/nixpkgs/pkgs/tools/text/platinum-searcher/default.nix
new file mode 100644
index 000000000000..ca89b7dc2d8a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/platinum-searcher/default.nix
@@ -0,0 +1,24 @@
+{ lib, buildGoPackage, fetchFromGitHub }:
+
+buildGoPackage rec {
+  pname = "the_platinum_searcher";
+  version = "2.1.5";
+  rev = "v${version}";
+
+  goPackagePath = "github.com/monochromegane/the_platinum_searcher";
+
+  src = fetchFromGitHub {
+    inherit rev;
+    owner = "monochromegane";
+    repo = "the_platinum_searcher";
+    sha256 = "1y7kl3954dimx9hp2bf1vjg1h52hj1v6cm4f5nhrqzwrawp0b6q0";
+  };
+
+  goDeps = ./deps.nix;
+
+  meta = with lib; {
+    homepage = "https://github.com/monochromegane/the_platinum_searcher";
+    description = "A code search tool similar to ack and the_silver_searcher(ag)";
+    license = licenses.mit;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/platinum-searcher/deps.nix b/nixpkgs/pkgs/tools/text/platinum-searcher/deps.nix
new file mode 100644
index 000000000000..04fb9bd4be34
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/platinum-searcher/deps.nix
@@ -0,0 +1,83 @@
+[
+  {
+    goPackagePath = "gopkg.in/yaml.v2";
+    fetch = {
+      type = "git";
+      url = "https://gopkg.in/yaml.v2";
+      rev = "a5b47d31c556af34a302ce5d659e6fea44d90de0";
+      sha256 = "0v6l48fshdjrqzyq1kwn22gy7vy434xdr1i0lm3prsf6jbln9fam";
+    };
+  }
+  {
+    goPackagePath = "github.com/jessevdk/go-flags";
+    fetch = {
+      type = "git";
+      url = "https://github.com/jessevdk/go-flags";
+      rev = "4e64e4a4e2552194cf594243e23aa9baf3b4297e";
+      sha256 = "02x7f1wm8119s27h4dc3a4aw6shydnpnnkvzwg5xm0snn5kb4zxm";
+    };
+  }
+  {
+    goPackagePath = "github.com/BurntSushi/toml";
+    fetch = {
+      type = "git";
+      url = "https://github.com/BurntSushi/toml";
+      rev = "99064174e013895bbd9b025c31100bd1d9b590ca";
+      sha256 = "058qrar8rvw3wb0ci1mf1axnqq2729cvv9zmdr4ms2nn9s97yiz9";
+    };
+  }
+  {
+    goPackagePath = "golang.org/x/text";
+    fetch = {
+      type = "git";
+      url = "https://go.googlesource.com/text";
+      rev = "a49bea13b776691cb1b49873e5d8df96ec74831a";
+      sha256 = "1pcmgf88wml6ca8v63nh3nxsfvpzjv3c4qj2w2wkizbil826g7as";
+    };
+  }
+  {
+    goPackagePath = "github.com/monochromegane/conflag";
+    fetch = {
+      type = "git";
+      url = "https://github.com/monochromegane/conflag";
+      rev = "6d68c9aa4183844ddc1655481798fe4d90d483e9";
+      sha256 = "0csfr5c8d3kbna9sqhzfp2z06wq6mc6ijja1zj2i82kzsq8534wa";
+    };
+  }
+  {
+    goPackagePath = "github.com/monochromegane/go-home";
+    fetch = {
+      type = "git";
+      url = "https://github.com/monochromegane/go-home";
+      rev = "25d9dda593924a11ea52e4ffbc8abdb0dbe96401";
+      sha256 = "172chakrj22xfm0bcda4qj5zqf7lwr53pzwc3xj6wz8vd2bcxkww";
+    };
+  }
+  {
+    goPackagePath = "github.com/monochromegane/terminal";
+    fetch = {
+      type = "git";
+      url = "https://github.com/monochromegane/terminal";
+      rev = "2da212063ce19aed90ee5bbb00ad1ad7393d7f48";
+      sha256 = "1rddaq9pk5q57ildms35iihghqk505gb349pb0f6k3svchay38nh";
+    };
+  }
+  {
+    goPackagePath = "github.com/monochromegane/go-gitignore";
+    fetch = {
+      type = "git";
+      url = "https://github.com/monochromegane/go-gitignore";
+      rev = "38717d0a108ca0e5af632cd6845ca77d45b50729";
+      sha256 = "0r1inabpgg6sn6i47b02hcmd2p4dc1ab1mcy20mn1b2k3mpdj4b7";
+    };
+  }
+  {
+    goPackagePath = "github.com/shiena/ansicolor";
+    fetch = {
+      type = "git";
+      url = "https://github.com/shiena/ansicolor";
+      rev = "a422bbe96644373c5753384a59d678f7d261ff10";
+      sha256 = "1dcn8a9z6a5dxa2m3fkppnajcls8lanbl38qggkf646yi5qsk1hc";
+    };
+  }
+]
diff --git a/nixpkgs/pkgs/tools/text/pn/default.nix b/nixpkgs/pkgs/tools/text/pn/default.nix
new file mode 100644
index 000000000000..81e4c1eb358a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/pn/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, cmake, libphonenumber, icu, protobuf }:
+
+stdenv.mkDerivation rec {
+  pname = "pn";
+  version = "unstable-2021-01-28";
+
+  src = fetchFromGitHub {
+    owner = "Orange-OpenSource";
+    repo = pname;
+    rev = "41e1215397129ed0d42b5f137fb35b5e0648edda";
+    sha256 = "1g8r7y230k01ghraa55g1bhz3fiz6bjdgcsddy2dfa5ih8c4s3jm";
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ libphonenumber icu protobuf ];
+
+  meta = with lib; {
+    description = "A libphonenumber command-line wrapper";
+    homepage = "https://github.com/Orange-OpenSource/pn";
+    license = licenses.asl20;
+    platforms = platforms.unix;
+    maintainers = [ maintainers.McSinyx ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/podiff/default.nix b/nixpkgs/pkgs/tools/text/podiff/default.nix
new file mode 100644
index 000000000000..2078c75f1362
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/podiff/default.nix
@@ -0,0 +1,25 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation {
+  pname = "podiff";
+  version = "1.3";
+
+  src = fetchurl {
+    url = "ftp://download.gnu.org.ua/pub/release/podiff/podiff-1.3.tar.gz";
+    sha256 = "sha256-7fpix+GkXsfpRgnkHtk1iXF6ILHri7BtUhNPK6sDQFA=";
+  };
+
+  patchPhase = ''
+    sed "s#PREFIX=/usr#PREFIX=$out#g" -i Makefile
+    mkdir -p $out/bin
+    mkdir -p $out/share/man/man1
+  '';
+
+  meta = with lib; {
+    description = "Finds differences in translations between two PO files, or revisions";
+    homepage = "http://puszcza.gnu.org.ua/software/podiff";
+    license = licenses.gpl3Plus;
+    maintainers = [ maintainers.goibhniu ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/poedit/default.nix b/nixpkgs/pkgs/tools/text/poedit/default.nix
new file mode 100644
index 000000000000..c53f521fddc4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/poedit/default.nix
@@ -0,0 +1,48 @@
+{ lib, stdenv, fetchFromGitHub, autoconf, automake, libtool, gettext, pkg-config, wxGTK31-gtk3,
+  boost, icu, lucenepp, asciidoc, libxslt, xmlto, gtk3, gtkspell3, pugixml,
+  nlohmann_json, hicolor-icon-theme, wrapGAppsHook }:
+
+stdenv.mkDerivation rec {
+  pname = "poedit";
+  version = "3.0";
+
+  src = fetchFromGitHub {
+    owner = "vslavik";
+    repo = "poedit";
+    rev = "v${version}-oss";
+    sha256 = "0bxhyxsa641ip6wab9ms9g4w6mb1bv46y5h5b436spl5c70rcn4z";
+  };
+
+  nativeBuildInputs = [ autoconf automake asciidoc wrapGAppsHook
+    libxslt xmlto boost libtool pkg-config ];
+
+  buildInputs = [ lucenepp nlohmann_json wxGTK31-gtk3 icu pugixml gtk3 gtkspell3 hicolor-icon-theme ];
+
+  propagatedBuildInputs = [ gettext ];
+
+  preConfigure = "
+    patchShebangs bootstrap
+    ./bootstrap
+  ";
+
+  configureFlags = [
+    "--without-cld2"
+    "--without-cpprest"
+    "--with-boost-libdir=${boost.out}/lib"
+    "CPPFLAGS=-I${nlohmann_json}/include/nlohmann/"
+  ];
+
+  preFixup = ''
+    gappsWrapperArgs+=(--prefix PATH : "${lib.makeBinPath [ gettext ]}")
+  '';
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    description = "Cross-platform gettext catalogs (.po files) editor";
+    homepage = "https://www.poedit.net/";
+    license = licenses.mit;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ dasj19 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/popfile/default.nix b/nixpkgs/pkgs/tools/text/popfile/default.nix
new file mode 100644
index 000000000000..7cfb2d2d6a4b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/popfile/default.nix
@@ -0,0 +1,60 @@
+{ lib, stdenv, fetchzip, makeWrapper, perlPackages,
+... }:
+
+stdenv.mkDerivation rec {
+  appname = "popfile";
+  version = "1.1.3";
+  name = "${appname}-${version}";
+
+  src = fetchzip {
+    url = "https://getpopfile.org/downloads/${appname}-${version}.zip";
+    sha256 = "0gcib9j7zxk8r2vb5dbdz836djnyfza36vi8215nxcdfx1xc7l63";
+    stripRoot = false;
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = (with perlPackages; [
+    ## These are all taken from the popfile documentation as applicable to Linux
+    ## https://getpopfile.org/docs/howtos:allplatformsrequireperl
+    perl
+    DBI
+    DBDSQLite
+    HTMLTagset
+    TimeDate # == DateParse
+    HTMLTemplate
+    # IO::Socket::Socks is not in nixpkgs
+    # IOSocketSocks
+    IOSocketSSL
+    NetSSLeay
+    SOAPLite
+  ]);
+
+  installPhase = ''
+    mkdir -p $out/bin
+    # I user `cd` rather than `cp $out/* ...` b/c the * breaks syntax
+    # highlighting in emacs for me.
+    cd $src
+    cp -r * $out/bin
+    cd $out/bin
+    chmod +x *.pl
+
+    find $out -name '*.pl' -executable | while read path; do
+      wrapProgram "$path" \
+        --prefix PERL5LIB : $PERL5LIB:$out/bin \
+        --set POPFILE_ROOT $out/bin \
+        --run 'export POPFILE_USER=''${POPFILE_USER:-$HOME/.popfile}' \
+        --run 'test -d "$POPFILE_USER" || mkdir -m 0700 -p "$POPFILE_USER"'
+    done
+  '';
+
+  meta = {
+    description = "An email classification system that automatically sorts messages and fights spam";
+    homepage = "http://getpopfile.org";
+    license = lib.licenses.gpl2;
+
+    # Should work on macOS, but havent tested it.
+    # Windows support is more complicated.
+    # https://getpopfile.org/docs/faq:systemrequirements
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/proselint/default.nix b/nixpkgs/pkgs/tools/text/proselint/default.nix
new file mode 100644
index 000000000000..d00b71977a22
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/proselint/default.nix
@@ -0,0 +1,22 @@
+{ lib, fetchurl, buildPythonApplication, click, future, six }:
+
+buildPythonApplication rec {
+  pname = "proselint";
+  version = "0.12.0";
+
+  doCheck = false; # fails to pass because it tries to run in home directory
+
+  src = fetchurl {
+    url = "mirror://pypi/p/proselint/${pname}-${version}.tar.gz";
+    sha256 = "2a98d9c14382d94ed9122a6c0b0657a814cd5c892c77d9477309fc99f86592e6";
+  };
+
+  propagatedBuildInputs = [ click future six ];
+
+  meta = with lib; {
+    description = "A linter for prose";
+    homepage = "http://proselint.com";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ alibabzo ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/qgrep/default.nix b/nixpkgs/pkgs/tools/text/qgrep/default.nix
new file mode 100644
index 000000000000..032e9474128a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/qgrep/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, fetchFromGitHub, CoreServices, CoreFoundation, fetchpatch }:
+
+stdenv.mkDerivation rec {
+  version = "1.1";
+  pname = "qgrep";
+
+  src = fetchFromGitHub {
+    owner = "zeux";
+    repo = "qgrep";
+    rev = "v${version}";
+    sha256 = "046ccw34vz2k5jn6gyxign5gs2qi7i50jy9b74wqv7sjf5zayrh0";
+    fetchSubmodules = true;
+  };
+
+  patches = lib.optionals stdenv.isDarwin [
+    (fetchpatch {
+      url = "https://github.com/zeux/qgrep/commit/21c4d1a5ab0f0bdaa0b5ca993c1315c041418cc6.patch";
+      sha256 = "0wpxzrd9pmhgbgby17vb8279xwvkxfdd99gvv7r74indgdxqg7v8";
+    })
+  ];
+
+  buildInputs = lib.optionals stdenv.isDarwin [ CoreServices CoreFoundation ];
+
+  postPatch = lib.optionalString stdenv.isAarch64 ''
+    substituteInPlace Makefile \
+      --replace "-msse2" "" --replace "-DUSE_SSE2" ""
+  '';
+
+  installPhase = ''
+    install -Dm755 qgrep $out/bin/qgrep
+  '';
+
+  meta = with lib; {
+    description = "Fast regular expression grep for source code with incremental index updates";
+    homepage = "https://github.com/zeux/qgrep";
+    license = licenses.mit;
+    maintainers = [ maintainers.yrashk ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/qprint/default.nix b/nixpkgs/pkgs/tools/text/qprint/default.nix
new file mode 100644
index 000000000000..19f2d7b1cbd6
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/qprint/default.nix
@@ -0,0 +1,29 @@
+{ fetchurl, lib, stdenv }:
+
+stdenv.mkDerivation rec {
+  pname = "qprint";
+  version = "1.1";
+
+  src = fetchurl {
+    url = "https://www.fourmilab.ch/webtools/qprint/qprint-${version}.tar.gz";
+    sha256 = "1701cnb1nl84rmcpxzq11w4cyj4385jh3gx4aqxznwf8a4fwmagz";
+  };
+
+  doCheck = true;
+
+  checkTarget = "wringer";
+
+  preInstall = ''
+    mkdir -p $out/bin
+    mkdir -p $out/share/man/man1
+  '';
+
+  meta = {
+    homepage = "http://www.fourmilab.ch/webtools/qprint/";
+    license = lib.licenses.publicDomain;
+    description = "Encode and decode Quoted-Printable files";
+    maintainers = [ lib.maintainers.tv ];
+    platforms = lib.platforms.all;
+  };
+
+}
diff --git a/nixpkgs/pkgs/tools/text/qshowdiff/default.nix b/nixpkgs/pkgs/tools/text/qshowdiff/default.nix
new file mode 100644
index 000000000000..251427f03c5b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/qshowdiff/default.nix
@@ -0,0 +1,25 @@
+{lib, stdenv, fetchurl, qt4, perl, pkg-config }:
+
+stdenv.mkDerivation rec {
+  pname = "qshowdiff";
+  version = "1.2";
+
+  src = fetchurl {
+    url = "https://github.com/danfis/qshowdiff/archive/v${version}.tar.gz";
+    sha256 = "027959xbzvi5c2w9y1x122sr5i26k9mvp43banz2wln6gd860n1a";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ qt4 perl ];
+
+  configurePhase = ''
+    mkdir -p $out/{bin,man/man1}
+    makeFlags="PREFIX=$out CC=$CXX"
+  '';
+
+  meta = {
+    homepage = "http://qshowdiff.danfis.cz/";
+    description = "Colourful diff viewer";
+    license = lib.licenses.gpl3Plus;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/reckon/Gemfile b/nixpkgs/pkgs/tools/text/reckon/Gemfile
new file mode 100644
index 000000000000..f708ddd93664
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/reckon/Gemfile
@@ -0,0 +1,2 @@
+source 'https://rubygems.org'
+gem 'reckon'
diff --git a/nixpkgs/pkgs/tools/text/reckon/Gemfile.lock b/nixpkgs/pkgs/tools/text/reckon/Gemfile.lock
new file mode 100644
index 000000000000..18dc624c3da1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/reckon/Gemfile.lock
@@ -0,0 +1,19 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    chronic (0.10.2)
+    highline (2.0.3)
+    rchardet (1.8.0)
+    reckon (0.8.0)
+      chronic (>= 0.3.0)
+      highline (>= 1.5.2)
+      rchardet (>= 1.8.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  reckon
+
+BUNDLED WITH
+   2.2.20
diff --git a/nixpkgs/pkgs/tools/text/reckon/default.nix b/nixpkgs/pkgs/tools/text/reckon/default.nix
new file mode 100644
index 000000000000..91233dfe97b4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/reckon/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, lib, bundlerEnv, bundlerUpdateScript, makeWrapper }:
+
+stdenv.mkDerivation rec {
+  pname = "reckon";
+  version = (import ./gemset.nix).reckon.version;
+
+  dontUnpack = true;
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  installPhase = let
+    env = bundlerEnv {
+      name = "${pname}-${version}-gems";
+
+      gemdir = ./.;
+    };
+  in ''
+    runHook preInstall
+    mkdir -p $out/bin
+    makeWrapper ${env}/bin/reckon $out/bin/reckon
+    runHook postInstall
+  '';
+
+  passthru.updateScript = bundlerUpdateScript "reckon";
+
+  meta = with lib; {
+    description = "Flexibly import bank account CSV files into Ledger for command line accounting";
+    license = licenses.mit;
+    maintainers = with maintainers; [ nicknovitski ];
+    platforms = platforms.unix;
+    changelog = "https://github.com/cantino/reckon/blob/v${version}/CHANGELOG.md";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/reckon/gemset.nix b/nixpkgs/pkgs/tools/text/reckon/gemset.nix
new file mode 100644
index 000000000000..0e2cc48886a4
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/reckon/gemset.nix
@@ -0,0 +1,43 @@
+{
+  chronic = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1hrdkn4g8x7dlzxwb1rfgr8kw3bp4ywg5l4y4i9c2g5cwv62yvvn";
+      type = "gem";
+    };
+    version = "0.10.2";
+  };
+  highline = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yclf57n2j3cw8144ania99h1zinf8q3f5zrhqa754j6gl95rp9d";
+      type = "gem";
+    };
+    version = "2.0.3";
+  };
+  rchardet = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1isj1b3ywgg2m1vdlnr41lpvpm3dbyarf1lla4dfibfmad9csfk9";
+      type = "gem";
+    };
+    version = "1.8.0";
+  };
+  reckon = {
+    dependencies = ["chronic" "highline" "rchardet"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qnghypb9pj7888096xwyrx7myhzk85x69ympxkxki3kxcgcrdfn";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/recode/default.nix b/nixpkgs/pkgs/tools/text/recode/default.nix
new file mode 100644
index 000000000000..ce377fada9f3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/recode/default.nix
@@ -0,0 +1,25 @@
+{ lib, stdenv, fetchurl, python3, perl, intltool, flex, texinfo, libiconv, libintl }:
+
+stdenv.mkDerivation rec {
+  pname = "recode";
+  version = "3.7.9";
+
+  # Use official tarball, avoid need to bootstrap/generate build system
+  src = fetchurl {
+    url = "https://github.com/rrthomas/${pname}/releases/download/v${version}/${pname}-${version}.tar.gz";
+    sha256 = "sha256-5DIKaw9c2DfNtFT7WFQBjd+pcJEWCOHwHMLGX2M2csQ=";
+  };
+
+  nativeBuildInputs = [ python3 python3.pkgs.cython perl intltool flex texinfo libiconv ];
+  buildInputs = [ libintl ];
+
+  doCheck = true;
+
+  meta = {
+    homepage = "https://github.com/rrthomas/recode";
+    description = "Converts files between various character sets and usages";
+    platforms = lib.platforms.unix;
+    license = lib.licenses.gpl2Plus;
+    maintainers = with lib.maintainers; [ jcumming ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/replace/default.nix b/nixpkgs/pkgs/tools/text/replace/default.nix
new file mode 100644
index 000000000000..a0873d1c8d2b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/replace/default.nix
@@ -0,0 +1,30 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "replace";
+  version = "2.24";
+
+  src = fetchurl {
+    url = "http://hpux.connect.org.uk/ftp/hpux/Users/replace-${version}/replace-${version}-src-11.31.tar.gz";
+    sha256 = "18hkwhaz25s6209n5mpx9hmkyznlzygqj488p2l7nvp9zrlxb9sf";
+  };
+
+  outputs = [ "out" "man" ];
+
+  makeFlags = [ "TREE=\$(out)" "MANTREE=\$(TREE)/share/man" ];
+
+  preBuild = ''
+    sed -e "s@/bin/mv@$(type -P mv)@" -i replace.h
+  '';
+
+  preInstall = "mkdir -p \$out/share/man";
+  postInstall = "mv \$out/bin/replace \$out/bin/replace-literal";
+
+  patches = [./malloc.patch];
+
+  meta = {
+    homepage = "https://replace.richardlloyd.org.uk/";
+    description = "A tool to replace verbatim strings";
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/replace/malloc.patch b/nixpkgs/pkgs/tools/text/replace/malloc.patch
new file mode 100644
index 000000000000..1ee95c4bae18
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/replace/malloc.patch
@@ -0,0 +1,13 @@
+diff -rc replace-2.24-orig/replace.h replace-2.24/replace.h
+*** replace-2.24-orig/replace.h	2004-10-07 15:15:06.000000000 +0200
+--- replace-2.24/replace.h	2008-02-21 14:57:47.000000000 +0100
+***************
+*** 11,17 ****
+  #include <ctype.h>
+  #include <unistd.h>
+  #include <string.h>
+- #include <malloc.h>
+  #include <sys/stat.h>
+  #include <ftw.h>
+  #include <utime.h>
+--- 11,16 ----
diff --git a/nixpkgs/pkgs/tools/text/rgxg/default.nix b/nixpkgs/pkgs/tools/text/rgxg/default.nix
new file mode 100644
index 000000000000..8e4d991e7bf0
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rgxg/default.nix
@@ -0,0 +1,18 @@
+{ lib, stdenv, fetchzip }:
+
+stdenv.mkDerivation rec {
+  pname = "rgxg";
+  version = "0.1.2";
+
+  src = fetchzip {
+    url = "https://github.com/rgxg/rgxg/releases/download/v${version}/${pname}-${version}.tar.gz";
+    sha256 = "050jxc3qhfrm9fdbzd67hlsqlp4qk1fa20q1g2v919sh7s6v77si";
+  };
+
+  meta = with lib; {
+    description = "A C library and a command-line tool to generate (extended) regular expressions";
+    license = licenses.zlib;
+    maintainers = with maintainers; [ hloeffler ];
+    homepage = "https://rgxg.github.io/";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ripgrep-all/default.nix b/nixpkgs/pkgs/tools/text/ripgrep-all/default.nix
new file mode 100644
index 000000000000..0fc39b8da280
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ripgrep-all/default.nix
@@ -0,0 +1,63 @@
+{ stdenv, lib, fetchFromGitHub, rustPlatform, makeWrapper, ffmpeg
+, pandoc, poppler_utils, ripgrep, Security, imagemagick, tesseract
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "ripgrep-all";
+  version = "0.9.6";
+
+  src = fetchFromGitHub {
+    owner = "phiresky";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "1wjpgi7m3lxybllkr3r60zaphp02ykq2syq72q9ail2760cjcir6";
+  };
+
+  cargoSha256 = "1l71xj5crfb51wfp2bdvdqp1l8kg182n5d6w23lq2wjszaqcj7cw";
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = lib.optional stdenv.isDarwin Security;
+
+  postInstall = ''
+    wrapProgram $out/bin/rga \
+      --prefix PATH ":" "${lib.makeBinPath [ ffmpeg pandoc poppler_utils ripgrep imagemagick tesseract ]}"
+  '';
+
+  # Use upstream's example data to run a couple of queries to ensure the dependencies
+  # for all of the adapters are available.
+  installCheckPhase = ''
+    set -e
+    export PATH="$PATH:$out/bin"
+
+    test1=$(rga --rga-no-cache "hello" exampledir/ | wc -l)
+    test2=$(rga --rga-no-cache --rga-adapters=tesseract "crate" exampledir/screenshot.png | wc -l)
+
+    if [ $test1 != 26 ]
+    then
+      echo "ERROR: test1 failed! Could not find the word 'hello' 26 times in the sample data."
+      exit 1
+    fi
+
+    if [ $test2 != 1 ]
+    then
+      echo "ERROR: test2 failed! Could not find the word 'crate' in the screenshot."
+      exit 1
+    fi
+  '';
+
+  doInstallCheck = true;
+
+  meta = with lib; {
+    description = "Ripgrep, but also search in PDFs, E-Books, Office documents, zip, tar.gz, and more";
+    longDescription = ''
+      Ripgrep, but also search in PDFs, E-Books, Office documents, zip, tar.gz, etc.
+
+      rga is a line-oriented search tool that allows you to look for a regex in
+      a multitude of file types. rga wraps the awesome ripgrep and enables it
+      to search in pdf, docx, sqlite, jpg, movie subtitles (mkv, mp4), etc.
+    '';
+    homepage = "https://github.com/phiresky/ripgrep-all";
+    license = with licenses; [ agpl3Plus ];
+    maintainers = with maintainers; [ zaninime ma27 ];
+    mainProgram = "rga";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ripgrep/default.nix b/nixpkgs/pkgs/tools/text/ripgrep/default.nix
new file mode 100644
index 000000000000..3fa202135f51
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ripgrep/default.nix
@@ -0,0 +1,56 @@
+{ lib, stdenv
+, fetchFromGitHub
+, rustPlatform
+, asciidoctor
+, installShellFiles
+, pkg-config
+, Security
+, withPCRE2 ? true
+, pcre2
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "ripgrep";
+  version = "13.0.0";
+
+  src = fetchFromGitHub {
+    owner = "BurntSushi";
+    repo = pname;
+    rev = version;
+    sha256 = "0pdcjzfi0fclbzmmf701fdizb95iw427vy3m1svy6gdn2zwj3ldr";
+  };
+
+  cargoSha256 = "1kfdgh8dra4jxgcdb0lln5wwrimz0dpp33bq3h7jgs8ngaq2a9wp";
+
+  cargoBuildFlags = lib.optional withPCRE2 "--features pcre2";
+
+  nativeBuildInputs = [ asciidoctor installShellFiles ]
+    ++ lib.optional withPCRE2 pkg-config;
+  buildInputs = lib.optional withPCRE2 pcre2
+    ++ lib.optional stdenv.isDarwin Security;
+
+  preFixup = ''
+    installManPage $releaseDir/build/ripgrep-*/out/rg.1
+
+    installShellCompletion $releaseDir/build/ripgrep-*/out/rg.{bash,fish}
+    installShellCompletion --zsh complete/_rg
+  '';
+
+  doInstallCheck = true;
+  installCheckPhase = ''
+    file="$(mktemp)"
+    echo "abc\nbcd\ncde" > "$file"
+    $out/bin/rg -N 'bcd' "$file"
+    $out/bin/rg -N 'cd' "$file"
+  '' + lib.optionalString withPCRE2 ''
+    echo '(a(aa)aa)' | $out/bin/rg -P '\((a*|(?R))*\)'
+  '';
+
+  meta = with lib; {
+    description = "A utility that combines the usability of The Silver Searcher with the raw speed of grep";
+    homepage = "https://github.com/BurntSushi/ripgrep";
+    license = with licenses; [ unlicense /* or */ mit ];
+    maintainers = with maintainers; [ tailhook globin ma27 zowoq ];
+    mainProgram = "rg";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/robodoc/default.nix b/nixpkgs/pkgs/tools/text/robodoc/default.nix
new file mode 100644
index 000000000000..e30e8739797a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/robodoc/default.nix
@@ -0,0 +1,48 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, autoreconfHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "robodoc";
+  version = "4.99.44";
+
+  src = fetchFromGitHub {
+    owner = "gumpu";
+    repo = "ROBODoc";
+    rev = "v${version}";
+    sha256 = "l3prSdaGhOvXmZfCPbsZJNocO7y20zJjLQpajRTJOqE=";
+  };
+
+  nativeBuildInputs = [ autoreconfHook ];
+
+  hardeningDisable = [ "format" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/gumpu/ROBODoc";
+    description = "Documentation Extraction Tool";
+    longDescription = ''
+      ROBODoc is program documentation tool. The idea is to include for every
+      function or procedure a standard header containing all sorts of
+      information about the procedure or function. ROBODoc extracts these
+      headers from the source file and puts them in a separate
+      autodocs-file. ROBODoc thus allows you to include the program
+      documentation in the source code and avoid having to maintain two separate
+      documents. Or as Petteri puts it: "robodoc is very useful - especially for
+      programmers who don't like writing documents with Word or some other
+      strange tool."
+
+      ROBODoc can format the headers in a number of different formats: HTML,
+      RTF, LaTeX, or XML DocBook. In HTML mode it can generate cross links
+      between headers. You can even include parts of your source code.
+
+      ROBODoc works with many programming languages: For instance C, Pascal,
+      Shell Scripts, Assembler, COBOL, Occam, Postscript, Forth, Tcl/Tk, C++,
+      Java -- basically any program in which you can use remarks/comments.
+    '';
+    license = with licenses; gpl3Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = with platforms; all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/rosie/default.nix b/nixpkgs/pkgs/tools/text/rosie/default.nix
new file mode 100644
index 000000000000..4f70f972b683
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rosie/default.nix
@@ -0,0 +1,47 @@
+{ stdenv
+, lib
+, fetchgit
+, libbsd
+, readline
+}:
+
+stdenv.mkDerivation rec {
+  pname = "rosie";
+  version = "unstable-2020-01-11";
+  src = fetchgit {
+    url = "https://gitlab.com/rosie-pattern-language/rosie";
+    rev = "670e9027563609ba2ea31e14e2621a1302742795";
+    sha256 = "0jc512dbn62a1fniknhbp6q0xa1p7xi3hn5v60is8sy9jgi3afxv";
+    fetchSubmodules = true;
+  };
+
+  postUnpack = ''
+    # The Makefile calls git to update submodules, unless this file exists
+    touch ${src.name}/submodules/~~present~~
+  '';
+
+  preConfigure = ''
+    patchShebangs src/build_info.sh
+    # Part of the same Makefile target which calls git to update submodules
+    ln -s src submodules/lua/include
+  '';
+
+  postInstall = ''
+    mkdir -p $out/share/emacs/site-lisp $out/share/vim-plugins $out/share/nvim
+    mv $out/lib/rosie/extra/extra/emacs/* $out/share/emacs/site-lisp/
+    mv $out/lib/rosie/extra/extra/vim $out/share/vim-plugins/rosie
+    ln -s $out/share/vim-plugins/rosie $out/share/nvim/site
+  '';
+
+  makeFlags = [ "DESTDIR=${placeholder "out"}" ];
+
+  buildInputs = [ libbsd readline ];
+
+  meta = with lib; {
+    homepage = "https://rosie-lang.org";
+    description = "Tools for searching using parsing expression grammars";
+    license = licenses.mit;
+    maintainers = with maintainers; [ kovirobi ];
+    platforms = with platforms; linux ++ darwin;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/rpl/default.nix b/nixpkgs/pkgs/tools/text/rpl/default.nix
new file mode 100644
index 000000000000..97a30211621c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rpl/default.nix
@@ -0,0 +1,23 @@
+{ lib, fetchFromGitHub, pythonPackages }:
+
+pythonPackages.buildPythonApplication rec {
+  pname = "rpl";
+  version = "1.5.7";
+
+  # Tests not included in pip package.
+  doCheck = false;
+
+  src = fetchFromGitHub {
+    owner  = "kcoyner";
+    repo   = "rpl";
+    rev    = "v${version}";
+    sha256 = "1xhpgcmq91ivy9ijfyz5ilg51m7fz8ar2077r7gq246j8gbf8ggr";
+  };
+
+  meta = with lib; {
+    description = "Replace strings in files";
+    homepage    = "https://github.com/kcoyner/rpl";
+    license     = licenses.gpl2;
+    maintainers = with maintainers; [ teto ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/rs/default.nix b/nixpkgs/pkgs/tools/text/rs/default.nix
new file mode 100644
index 000000000000..9aca92922a52
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rs/default.nix
@@ -0,0 +1,52 @@
+{ lib, stdenv, fetchurl, libbsd }:
+
+stdenv.mkDerivation rec {
+  pname = "rs";
+  version = "20200313";
+
+  src = fetchurl {
+    url = "https://www.mirbsd.org/MirOS/dist/mir/rs/${pname}-${version}.tar.gz";
+    sha256 = "0gxwlfk7bzivpp2260w2r6gkyl7vdi05cggn1fijfnp8kzf1b4li";
+  };
+
+  buildInputs = [ libbsd ];
+
+  buildPhase = ''
+    ${stdenv.cc}/bin/cc utf8.c rs.c -o rs -lbsd
+  '';
+
+  installPhase = ''
+    install -Dm 755 rs -t $out/bin
+    install -Dm 644 rs.1 -t $out/share/man/man1
+  '';
+
+  meta = with lib; {
+    description = "Reshape a data array from standard input";
+    longDescription = ''
+      rs reads the standard input, interpreting each line as a row of blank-
+      separated entries in an array, transforms the array according to the op-
+      tions, and writes it on the standard output. With no arguments (argc < 2)
+      it transforms stream input into a columnar format convenient for terminal
+      viewing, i.e. if the length (in bytes!) of the first line is smaller than
+      the display width, -et is implied, -t otherwise.
+
+      The shape of the input array is deduced from the number of lines and the
+      number of columns on the first line. If that shape is inconvenient, a more
+      useful one might be obtained by skipping some of the input with the -k
+      option. Other options control interpretation of the input columns.
+
+      The shape of the output array is influenced by the rows and cols specifi-
+      cations, which should be positive integers. If only one of them is a po-
+      sitive integer, rs computes a value for the other which will accommodate
+      all of the data. When necessary, missing data are supplied in a manner
+      specified by the options and surplus data are deleted. There are options
+      to control presentation of the output columns, including transposition of
+      the rows and columns.
+    '';
+
+    homepage = "https://www.mirbsd.org/htman/i386/man1/rs.htm";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/rst2html5/default.nix b/nixpkgs/pkgs/tools/text/rst2html5/default.nix
new file mode 100644
index 000000000000..5ae0caa34e13
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rst2html5/default.nix
@@ -0,0 +1,25 @@
+{ lib, python3Packages }:
+
+python3Packages.buildPythonPackage rec {
+  pname = "rst2html5";
+  version = "2.0";
+
+  src = python3Packages.fetchPypi {
+    inherit pname version;
+    hash = "sha256-Ejjja/fm6wXTf9YtjCYZsNDB8X5oAtyPoUIsYFDuZfc=";
+  };
+
+  buildInputs = with python3Packages; [
+    beautifulsoup4
+    docutils
+    genshi
+    pygments
+  ];
+
+  meta = with lib;{
+    homepage = "https://rst2html5.readthedocs.io/en/latest/";
+    description = "Converts ReSTructuredText to (X)HTML5";
+    license = licenses.mit;
+    maintainers = with maintainers; [ AndersonTorres ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile b/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile
new file mode 100644
index 000000000000..4bb5d8c175d7
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile
@@ -0,0 +1,2 @@
+source 'https://rubygems.org'
+gem 'ruby-zoom'
diff --git a/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile.lock b/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile.lock
new file mode 100644
index 000000000000..820a972d106d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ruby-zoom/Gemfile.lock
@@ -0,0 +1,24 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    djinni (2.2.4)
+      fagin (~> 1.2, >= 1.2.1)
+    fagin (1.2.1)
+    hilighter (1.2.3)
+    json_config (1.1.0)
+    ruby-zoom (5.3.0)
+      djinni (~> 2.2, >= 2.2.4)
+      fagin (~> 1.2, >= 1.2.1)
+      hilighter (~> 1.2, >= 1.2.3)
+      json_config (~> 1.0, >= 1.0.0)
+      scoobydoo (~> 1.0, >= 1.0.0)
+    scoobydoo (1.0.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  ruby-zoom
+
+BUNDLED WITH
+   1.17.2
diff --git a/nixpkgs/pkgs/tools/text/ruby-zoom/default.nix b/nixpkgs/pkgs/tools/text/ruby-zoom/default.nix
new file mode 100644
index 000000000000..965d23d0c44b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ruby-zoom/default.nix
@@ -0,0 +1,18 @@
+{ lib, bundlerEnv, ruby, bundlerUpdateScript }:
+
+bundlerEnv {
+  pname = "ruby-zoom";
+
+  inherit ruby;
+  gemdir = ./.;
+
+  passthru.updateScript = bundlerUpdateScript "ruby-zoom";
+
+  meta = with lib; {
+    description = "Quickly open CLI search results in your favorite editor!";
+    homepage    = "https://gitlab.com/mjwhitta/zoom";
+    license     = with licenses; gpl3;
+    maintainers = with maintainers; [ vmandela nicknovitski ];
+    platforms   = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ruby-zoom/gemset.nix b/nixpkgs/pkgs/tools/text/ruby-zoom/gemset.nix
new file mode 100644
index 000000000000..19584787d904
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ruby-zoom/gemset.nix
@@ -0,0 +1,64 @@
+{
+  djinni = {
+    dependencies = ["fagin"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "18zk80jk70xq1bnsvzcgxb13x9fqdb5g4m02b2f6mvqm4cyw26pl";
+      type = "gem";
+    };
+    version = "2.2.4";
+  };
+  fagin = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0psyydh4hf2s1kz0r50aiyjf5v2pqhkbmy0gicxzaj5n17q2ga24";
+      type = "gem";
+    };
+    version = "1.2.1";
+  };
+  hilighter = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "03zm49g96dfpan5fhblcjxrzv7ldwan57sn0jcllkcmrqfd0zlyz";
+      type = "gem";
+    };
+    version = "1.2.3";
+  };
+  json_config = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0slb618n1ipn47j6dsxbfv2j9pl06dxn2i651llix09d529m7zwa";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  ruby-zoom = {
+    dependencies = ["djinni" "fagin" "hilighter" "json_config" "scoobydoo"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0iqxc0rzypsxy4wbxnvgvk98dbcsrcczq3xi9xd4wz4ggwq564l3";
+      type = "gem";
+    };
+    version = "5.3.0";
+  };
+  scoobydoo = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "162p75nc9x078kqcpdsrsd7kngs6jc5n4injz3kzpwf0jgbbm8n7";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/runiq/default.nix b/nixpkgs/pkgs/tools/text/runiq/default.nix
new file mode 100644
index 000000000000..6d7bb5e7eb0b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/runiq/default.nix
@@ -0,0 +1,20 @@
+{ fetchCrate, lib, rustPlatform }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "runiq";
+  version = "1.2.1";
+
+  src = fetchCrate {
+    inherit pname version;
+    sha256 = "0xhd1z8mykxg9kiq8nw5agy1jxfk414czq62xm1s13ssig3h7jqj";
+  };
+
+  cargoSha256 = "1g4yfz5xq9lqwh0ggyn8kn8bnzrqfmh7kx455md5ranrqqh0x5db";
+
+  meta = with lib; {
+    description = "An efficient way to filter duplicate lines from input, à la uniq";
+    homepage = "https://github.com/whitfin/runiq";
+    license = licenses.mit;
+    maintainers = with maintainers; [ figsoda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ruplacer/default.nix b/nixpkgs/pkgs/tools/text/ruplacer/default.nix
new file mode 100644
index 000000000000..ccf1abe53962
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ruplacer/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, Security }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "ruplacer";
+  version = "0.6.2";
+
+  src = fetchFromGitHub {
+    owner = "TankerHQ";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-gme/p/F+LvfzynPNKmaPbNsKbwNKFCeEbAADk5PyMh8=";
+  };
+
+  cargoSha256 = "sha256-/37TBl/FnCtkiufusPuJIpirD2WVO882xSqrfWVMNW0=";
+
+  buildInputs = (lib.optional stdenv.isDarwin Security);
+
+  meta = with lib; {
+    description = "Find and replace text in source files";
+    homepage = "https://github.com/TankerHQ/ruplacer";
+    license = [ licenses.bsd3 ];
+    maintainers = with maintainers; [ Br1ght0ne ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/rust-petname/default.nix b/nixpkgs/pkgs/tools/text/rust-petname/default.nix
new file mode 100644
index 000000000000..4a3c0f596cfb
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/rust-petname/default.nix
@@ -0,0 +1,22 @@
+{ lib, rustPlatform, fetchCrate }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "rust-petname";
+  version = "1.1.1";
+
+  src = fetchCrate {
+    inherit version;
+    crateName = "petname";
+    sha256 = "sha256-X1p9W+N0Nhh7CSh776ofzHmG0ayi5COLJjBncxmL8CM=";
+  };
+
+  cargoSha256 = "sha256-jxN2EKLjf9yKkhZ4wsH72sNdk6UYAcCUrg4+qx75bWs=";
+
+  meta = with lib; {
+    description = "Generate human readable random names";
+    homepage = "https://github.com/allenap/rust-petname";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ figsoda ];
+    mainProgram = "petname";
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sad/default.nix b/nixpkgs/pkgs/tools/text/sad/default.nix
new file mode 100644
index 000000000000..2b748d60d1fe
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sad/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, fetchFromGitHub
+, rustPlatform
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "sad";
+  version = "0.4.14";
+
+  src = fetchFromGitHub {
+    owner = "ms-jpq";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "03b6qxkn8sqv06gs4p6wg02arz0n9llc3z92zhfd5ipz8han83fd";
+  };
+
+  cargoSha256 = "13nkd4354siy8pr2032bxz2z5x8b378mccq6pnm71cpl9dl6w4ad";
+
+  meta = with lib; {
+    description = "CLI tool to search and replace";
+    homepage = "https://github.com/ms-jpq/sad";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/schema2ldif/default.nix b/nixpkgs/pkgs/tools/text/schema2ldif/default.nix
new file mode 100644
index 000000000000..84196ae11197
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/schema2ldif/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl, makeWrapper, perlPackages }:
+
+stdenv.mkDerivation rec {
+  pname = "schema2ldif";
+  version = "1.3";
+
+  src = fetchurl {
+    url = "https://repos.fusiondirectory.org/sources/schema2ldif/schema2ldif-${version}.tar.gz";
+    sha256 = "00cd9xx9g0mnnfn5lvay3vg166z84jla0ya1x34ljdc8bflxsr9a";
+  };
+
+  buildInputs = [ perlPackages.perl ];
+  nativeBuildInputs = [ makeWrapper ];
+
+  installPhase = ''
+    mkdir -p $out/bin $out/share/man/man1
+
+    cp bin/{schema2ldif,ldap-schema-manager} $out/bin
+    gzip -c man/schema2ldif.1 > $out/share/man/man1/schema2ldif.1.gz
+    gzip -c man/ldap-schema-manager.1 > $out/share/man/man1/ldap-schema-manager.1.gz
+
+    wrapProgram $out/bin/schema2ldif \
+       --prefix PERL5PATH : "${perlPackages.makePerlPath [ perlPackages.GetoptLong ]}"
+  '';
+
+  meta = with lib; {
+    description = "Utilities to manage schema in .schema and .ldif format";
+    homepage = "https://www.fusiondirectory.org/schema2ldif-project-and-components/";
+    license = licenses.bsd3;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ das_j ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sd/default.nix b/nixpkgs/pkgs/tools/text/sd/default.nix
new file mode 100644
index 000000000000..009150062db2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sd/default.nix
@@ -0,0 +1,34 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, installShellFiles, Security
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "sd";
+  version = "0.7.6";
+
+  src = fetchFromGitHub {
+    owner = "chmln";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "0c5bsqs6c55x4j640vhzlmbiylhp5agr7lx0jrwcjazfyvxihc01";
+  };
+
+  cargoSha256 = "1iwgy9zzdxay6hb9pz47jchy03jrsy5csxijlq4i228qhqnvq1lr";
+
+  nativeBuildInputs = [ installShellFiles ];
+
+  buildInputs = lib.optionals stdenv.isDarwin [ Security ];
+
+  preFixup = ''
+    installManPage $releaseDir/build/sd-*/out/sd.1
+
+    installShellCompletion $releaseDir/build/sd-*/out/sd.{bash,fish}
+    installShellCompletion --zsh $releaseDir/build/sd-*/out/_sd
+  '';
+
+  meta = with lib; {
+    description = "Intuitive find & replace CLI (sed alternative)";
+    homepage = "https://github.com/chmln/sd";
+    license = licenses.mit;
+    maintainers = with maintainers; [ amar1729 Br1ght0ne ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sgml/jade/default.nix b/nixpkgs/pkgs/tools/text/sgml/jade/default.nix
new file mode 100644
index 000000000000..338520b4df2b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sgml/jade/default.nix
@@ -0,0 +1,39 @@
+{ lib, stdenv, fetchurl, gnum4 }:
+
+stdenv.mkDerivation rec {
+  name = "jade-${version}-${debpatch}";
+  version = "1.2.1";
+  debpatch = "47.3";
+
+  src = fetchurl {
+    url = "ftp://ftp.jclark.com/pub/jade/jade-${version}.tar.gz";
+    sha256 = "84e2f8a2a87aab44f86a46b71405d4f919b219e4c73e03a83ab6c746a674b187";
+  };
+
+  patchsrc =  fetchurl {
+    url = "http://ftp.debian.org/debian/pool/main/j/jade/jade_${version}-${debpatch}.diff.gz";
+    sha256 = "8e94486898e3503308805f856a65ba5b499a6f21994151270aa743de48305464";
+  };
+
+  patches = [ patchsrc ];
+
+  buildInputs = [ gnum4 ];
+
+  NIX_CFLAGS_COMPILE = "-Wno-deprecated";
+
+  preInstall = ''
+    install -d -m755 "$out"/lib
+  '';
+
+  postInstall = ''
+    mv "$out/bin/sx" "$out/bin/sgml2xml"
+  '';
+
+  meta = {
+    description = "James Clark's DSSSL Engine";
+    license = "custom";
+    homepage = "http://www.jclark.com/jade/";
+    platforms = with lib.platforms; linux;
+    maintainers = with lib.maintainers; [ e-user ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sgml/openjade/default.nix b/nixpkgs/pkgs/tools/text/sgml/openjade/default.nix
new file mode 100644
index 000000000000..f87bd5d7b1a1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sgml/openjade/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchurl, opensp, perl }:
+
+stdenv.mkDerivation rec {
+  pname = "openjade";
+  version = "1.3.2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/openjade/openjade-${version}.tar.gz";
+    sha256 = "1l92sfvx1f0wmkbvzv1385y1gb3hh010xksi1iyviyclrjb7jb8x";
+  };
+
+  patches = [ ./msggen.patch ];
+
+  buildInputs = [ opensp perl ];
+
+  configureFlags = [
+    "--enable-spincludedir=${opensp}/include/OpenSP"
+    "--enable-splibdir=${opensp}/lib"
+  ];
+
+  meta = {
+    description = "An implementation of DSSSL, an ISO standard for formatting SGML (and XML) documents";
+    license = lib.licenses.mit;
+    homepage = "http://openjade.sourceforge.net/";
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sgml/openjade/msggen.patch b/nixpkgs/pkgs/tools/text/sgml/openjade/msggen.patch
new file mode 100644
index 000000000000..d59573fa49cf
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sgml/openjade/msggen.patch
@@ -0,0 +1,34 @@
+http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/app-text/openjade/files/openjade-1.3.2-msggen.pl.patch?revision=1.2
+
+Use Getopt::Std in place of getopts.pl.
+https://bugs.gentoo.org/show_bug.cgi?id=420083
+
+--- a/msggen.pl
++++ b/msggen.pl
+@@ -4,6 +4,7 @@
+ # See the file COPYING for copying permission.
+ 
+ use POSIX;
++use Getopt::Std;
+ 
+ # Package and version.
+ $package = 'openjade';
+@@ -18,8 +19,7 @@
+ undef $opt_l;
+ undef $opt_p;
+ undef $opt_t;
+-do 'getopts.pl';
+-&Getopts('l:p:t:');
++getopts('l:p:t:');
+ $module = $opt_l;
+ $pot_file = $opt_p;
+ 
+@@ -72,7 +72,7 @@
+     else {
+ 	$field[0] =~ /^[IWQXE][0-9]$/ || &error("invalid first field");;
+ 	$type[$num] = substr($field[0], 0, 1);
+-	$argc = int(substr($field[0], 1, 1));
++	$argc = substr($field[0], 1, 1);
+     }
+     $nargs[$num] = $argc;
+     $field[1] =~ /^[a-zA-Z_][a-zA-Z0-9_]+$/ || &error("invalid tag");
diff --git a/nixpkgs/pkgs/tools/text/sgml/opensp/default.nix b/nixpkgs/pkgs/tools/text/sgml/opensp/default.nix
new file mode 100644
index 000000000000..6924c8953eef
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sgml/opensp/default.nix
@@ -0,0 +1,48 @@
+{ lib, stdenv, fetchurl, fetchpatch, xmlto, docbook_xml_dtd_412
+, libxslt, docbook_xsl, autoconf, automake, gettext, libiconv, libtool}:
+
+stdenv.mkDerivation rec {
+  pname = "opensp";
+  version = "1.5.2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/openjade/OpenSP-${version}.tar.gz";
+    sha256 = "1khpasr6l0a8nfz6kcf3s81vgdab8fm2dj291n5r2s53k228kx2p";
+  };
+
+  postPatch = ''
+    sed -i s,/usr/share/sgml/docbook/xml-dtd-4.1.2/,${docbook_xml_dtd_412}/xml/dtd/docbook/, \
+      docsrc/*.xml
+  '';
+
+  patches = [
+    (fetchpatch {
+      url = "https://gitweb.gentoo.org/repo/gentoo.git/plain/app-text/opensp/files/opensp-1.5.2-c11-using.patch?id=688d9675782dfc162d4e6cff04c668f7516118d0";
+      sha256 = "04q14s8qsad0bkjmj067dn831i0r6v7742rafdlnbfm5y249m2q6";
+    })
+  ];
+
+  setupHook = ./setup-hook.sh;
+
+  postFixup = ''
+    # Remove random ids in the release notes
+    sed -i -e 's/href="#idm.*"//g' $out/share/doc/OpenSP/releasenotes.html
+    sed -i -e 's/name="idm.*"//g' $out/share/doc/OpenSP/releasenotes.html
+    '';
+
+  preConfigure = if stdenv.isCygwin then "autoreconf -fi" else null;
+
+  # need autoconf, automake, gettext, and libtool for reconfigure
+  nativeBuildInputs = lib.optionals stdenv.isCygwin [ autoconf automake libtool ];
+
+  buildInputs = [ xmlto docbook_xml_dtd_412 libxslt docbook_xsl gettext libiconv ];
+
+  doCheck = false; # fails
+
+  meta = {
+    description = "A suite of SGML/XML processing tools";
+    license = lib.licenses.mit;
+    homepage = "http://openjade.sourceforge.net/";
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sgml/opensp/setup-hook.sh b/nixpkgs/pkgs/tools/text/sgml/opensp/setup-hook.sh
new file mode 100644
index 000000000000..5bace3c66889
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sgml/opensp/setup-hook.sh
@@ -0,0 +1,22 @@
+addSGMLCatalogs () {
+      if test -d $1/sgml/dtd; then
+          for i in $(find $1/sgml/dtd -name docbook.cat); do
+              export SGML_CATALOG_FILES="${SGML_CATALOG_FILES:+:}$i"
+          done
+      fi
+}
+
+if test -z "${sgmlHookDone-}"; then
+    sgmlHookDone=1
+
+    # Set http_proxy and ftp_proxy to a invalid host to prevent
+    # xmllint and xsltproc from trying to download DTDs from the
+    # network even when --nonet is not given.  That would be impure.
+    # (Note that .invalid is a reserved domain guaranteed not to
+    # work.)
+    export http_proxy=http://nodtd.invalid/
+    export ftp_proxy=http://nodtd.invalid/
+
+    export SGML_CATALOG_FILES
+    addEnvHooks "$targetOffset" addSGMLCatalogs
+fi
diff --git a/nixpkgs/pkgs/tools/text/shab/default.nix b/nixpkgs/pkgs/tools/text/shab/default.nix
new file mode 100644
index 000000000000..b5bb98e5f4d2
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/shab/default.nix
@@ -0,0 +1,73 @@
+{ bash, stdenv, lib, runCommand, writeText, fetchFromGitHub }:
+let
+  version = "1.0.0";
+
+  shab = stdenv.mkDerivation {
+    pname = "shab";
+    inherit version;
+
+    src = fetchFromGitHub {
+      owner = "zimbatm";
+      repo = "shab";
+      rev = "v${version}";
+      sha256 = "02lf1s6plhhcfyj9xha44wij9jbphb1x5q55xj3b5bx2ji2jsvji";
+    };
+
+    postPatch = ''
+      for f in test.sh test/*.sh; do
+        patchShebangs "$f"
+      done
+    '';
+
+    doCheck = true;
+    doInstallCheck = true;
+
+    checkPhase = ''
+      ./test.sh
+    '';
+
+    installPhase = ''
+      mkdir -p $out/bin
+      cp ./shab $out/bin/shab
+    '';
+
+    installCheckPhase = ''
+      [[ "$(echo 'Hello $entity' | entity=world $out/bin/shab)" == 'Hello world' ]]
+    '';
+
+    passthru = {
+      inherit render renderText;
+    };
+
+    meta = with lib; {
+      description = "The bash templating language";
+      homepage = "https://github.com/zimbatm/shab";
+      license = licenses.unlicense;
+      maintainers = with maintainers; [ zimbatm ];
+      platforms = bash.meta.platforms;
+    };
+  };
+
+  /*
+     shabScript:       a path or filename to use as a template
+     parameters.name:  the name to use as part of the store path
+     parameters:       variables to expose to the template
+   */
+  render = shabScript: parameters:
+    let extraParams = {
+          inherit shabScript;
+        };
+    in runCommand "out" (parameters // extraParams) ''
+      ${shab}/bin/shab "$shabScript" >$out
+    '';
+
+  /*
+     shabScriptText:   a string to use as a template
+     parameters.name:  the name to use as part of the store path
+     parameters:       variables to expose to the template
+   */
+  renderText = shabScriptText: parameters:
+    render (writeText "template" shabScriptText) parameters;
+
+in
+  shab
diff --git a/nixpkgs/pkgs/tools/text/shfmt/default.nix b/nixpkgs/pkgs/tools/text/shfmt/default.nix
new file mode 100644
index 000000000000..b7b344ab135a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/shfmt/default.nix
@@ -0,0 +1,37 @@
+{ lib, buildGoModule, fetchFromGitHub, installShellFiles, scdoc }:
+
+buildGoModule rec {
+  pname = "shfmt";
+  version = "3.3.1";
+
+  src = fetchFromGitHub {
+    owner = "mvdan";
+    repo = "sh";
+    rev = "v${version}";
+    sha256 = "sha256-43v64TQS1xpmU9pyjSTgV03n7xYJR+JAfZVoK3vwbiY=";
+  };
+
+  vendorSha256 = "sha256-t1Zdn+NaHrKde6F5o86e+FmN3tH55YpZLuDhTv2lIf4=";
+
+  subPackages = [ "cmd/shfmt" ];
+
+  ldflags = [ "-s" "-w" "-X main.version=${version}" ];
+
+  nativeBuildInputs = [ installShellFiles scdoc ];
+
+  postBuild = ''
+    scdoc < cmd/shfmt/shfmt.1.scd > shfmt.1
+    installManPage shfmt.1
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/mvdan/sh";
+    description = "A shell parser and formatter";
+    longDescription = ''
+      shfmt formats shell programs. It can use tabs or any number of spaces to indent.
+      You can feed it standard input, any number of files or any number of directories to recurse into.
+    '';
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ zowoq SuperSandro2000 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/shocco/default.nix b/nixpkgs/pkgs/tools/text/shocco/default.nix
new file mode 100644
index 000000000000..11d8194bb702
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/shocco/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchFromGitHub, perlPackages, pythonPackages }:
+
+stdenv.mkDerivation rec {
+  pname = "shocco";
+  version = "1.0";
+
+  src = fetchFromGitHub {
+    owner = "rtomayko";
+    repo = "shocco";
+    rev = version;
+    sha256 = "1nkwcw9fqf4vyrwidqi6by7nrmainkjqkirkz3yxmzk6kzwr38mi";
+  };
+
+  prePatch = ''
+    # Don't change $PATH
+    substituteInPlace configure --replace PATH= NIRVANA=
+  '';
+
+  buildInputs = [ perlPackages.TextMarkdown pythonPackages.pygments ];
+
+  meta = with lib; {
+    description = "A quick-and-dirty, literate-programming-style documentation generator for / in POSIX shell";
+    homepage = "https://rtomayko.github.io/shocco/";
+    license = licenses.mit;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ dotlambda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sift/default.nix b/nixpkgs/pkgs/tools/text/sift/default.nix
new file mode 100644
index 000000000000..dc025f17a78b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sift/default.nix
@@ -0,0 +1,25 @@
+{ lib, buildGoPackage, fetchFromGitHub }:
+
+buildGoPackage rec {
+  pname = "sift";
+  version = "0.9.0";
+  rev = "v${version}";
+
+  goPackagePath = "github.com/svent/sift";
+
+  src = fetchFromGitHub {
+    inherit rev;
+    owner = "svent";
+    repo = "sift";
+    sha256 = "0bgy0jf84z1c3msvb60ffj4axayfchdkf0xjnsbx9kad1v10g7i1";
+  };
+
+  goDeps = ./deps.nix;
+
+  meta = with lib; {
+    description = "A fast and powerful alternative to grep";
+    homepage = "https://sift-tool.org";
+    maintainers = [ maintainers.carlsverre ];
+    license = licenses.gpl3;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/sift/deps.nix b/nixpkgs/pkgs/tools/text/sift/deps.nix
new file mode 100644
index 000000000000..038555fa3cab
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/sift/deps.nix
@@ -0,0 +1,29 @@
+[
+  {
+    goPackagePath = "golang.org/x/crypto";
+    fetch = {
+      type = "git";
+      url = "https://go.googlesource.com/crypto";
+      rev = "575fdbe86e5dd89229707ebec0575ce7d088a4a6";
+      sha256 = "1kgv1mkw9y404pk3lcwbs0vgl133mwyp294i18jg9hp10s5d56xa";
+    };
+  }
+  {
+    goPackagePath = "github.com/svent/go-flags";
+    fetch = {
+      type = "git";
+      url = "https://github.com/svent/go-flags";
+      rev = "4bcbad344f0318adaf7aabc16929701459009aa3";
+      sha256 = "1gb416fgxl9gq4q6wsv3i2grq1mzbi7lvfvmfdqbxqbv9vizzh34";
+    };
+  }
+  {
+    goPackagePath = "github.com/svent/go-nbreader";
+    fetch = {
+      type = "git";
+      url = "https://github.com/svent/go-nbreader";
+      rev = "7cef48da76dca6a496faa7fe63e39ed665cbd219";
+      sha256 = "0hw11jj5r3f6qwydg41nc3c6aadlbkhc1qpxra2609lis0qa9h4r";
+    };
+  }
+]
diff --git a/nixpkgs/pkgs/tools/text/silver-searcher/bash-completion.patch b/nixpkgs/pkgs/tools/text/silver-searcher/bash-completion.patch
new file mode 100644
index 000000000000..30e8c72389b7
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/silver-searcher/bash-completion.patch
@@ -0,0 +1,5 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -9 +9 @@
+-bashcompdir = $(pkgdatadir)/completions
++bashcompdir = $(datadir)/bash-completion/completions
diff --git a/nixpkgs/pkgs/tools/text/silver-searcher/default.nix b/nixpkgs/pkgs/tools/text/silver-searcher/default.nix
new file mode 100644
index 000000000000..757c65eed848
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/silver-searcher/default.nix
@@ -0,0 +1,29 @@
+{lib, stdenv, fetchFromGitHub, autoreconfHook, pkg-config, pcre, zlib, xz}:
+
+stdenv.mkDerivation rec {
+  pname = "silver-searcher";
+  version = "2.2.0";
+
+  src = fetchFromGitHub {
+    owner = "ggreer";
+    repo = "the_silver_searcher";
+    rev = version;
+    sha256 = "0cyazh7a66pgcabijd27xnk1alhsccywivv6yihw378dqxb22i1p";
+  };
+
+  patches = [ ./bash-completion.patch ];
+
+  NIX_LDFLAGS = lib.optionalString stdenv.isLinux "-lgcc_s";
+
+  nativeBuildInputs = [ autoreconfHook pkg-config ];
+  buildInputs = [ pcre zlib xz ];
+
+  meta = with lib; {
+    homepage = "https://github.com/ggreer/the_silver_searcher/";
+    description = "A code-searching tool similar to ack, but faster";
+    maintainers = with maintainers; [ madjar ];
+    mainProgram = "ag";
+    platforms = platforms.all;
+    license = licenses.asl20;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/smu/default.nix b/nixpkgs/pkgs/tools/text/smu/default.nix
new file mode 100644
index 000000000000..854e70c7622b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/smu/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, lib, fetchFromGitHub }:
+
+stdenv.mkDerivation rec {
+  name = "smu";
+  version = "1.5";
+
+  src = fetchFromGitHub {
+    owner = "Gottox";
+    repo = "smu";
+    rev = "v${version}";
+    sha256 = "1jm7lhnzjx4q7gcwlkvsbffcy0zppywyh50d71ami6dnq182vvcc";
+  };
+
+  # _FORTIFY_SOURCE requires compiling with optimization (-O)
+  NIX_CFLAGS_COMPILE = "-O";
+
+  makeFlags = [
+    "PREFIX=${placeholder "out"}"
+  ];
+
+  meta = with lib; {
+    description = "simple markup - markdown like syntax";
+    homepage = "https://github.com/Gottox/smu";
+    license = licenses.mit;
+    maintainers = with maintainers; [ oxzi ];
+  };
+}
+
diff --git a/nixpkgs/pkgs/tools/text/snippetpixie/default.nix b/nixpkgs/pkgs/tools/text/snippetpixie/default.nix
new file mode 100644
index 000000000000..e66a5404f439
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/snippetpixie/default.nix
@@ -0,0 +1,92 @@
+{ lib, stdenv
+, fetchFromGitHub
+, nix-update-script
+, meson
+, ninja
+, vala
+, pkg-config
+, wrapGAppsHook
+, appstream
+, desktop-file-utils
+, python3
+, libgee
+, glib
+, gtk3
+, sqlite
+, at-spi2-atk
+, at-spi2-core
+, dbus
+, ibus
+, json-glib
+, pantheon
+, xorg
+}:
+
+stdenv.mkDerivation rec {
+  pname = "snippetpixie";
+  version = "1.5.3";
+
+  src = fetchFromGitHub {
+    owner = "bytepixie";
+    repo = pname;
+    rev = version;
+    sha256 = "0gs3d9hdywg4vcfbp4qfcagfjqalfgw9xpvywg4pw1cm3rzbdqmz";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    vala
+    pkg-config
+    wrapGAppsHook
+    appstream
+    desktop-file-utils
+    python3
+  ];
+
+  buildInputs = [
+    libgee
+    glib
+    gtk3
+    sqlite
+    at-spi2-atk
+    at-spi2-core
+    dbus
+    ibus
+    json-glib
+    xorg.libXtst
+    pantheon.granite
+    pantheon.elementary-gtk-theme
+    pantheon.elementary-icon-theme
+  ];
+
+  doCheck = true;
+
+  postPatch = ''
+    chmod +x meson/post_install.py
+    patchShebangs meson/post_install.py
+  '';
+
+  passthru = {
+    updateScript = nix-update-script {
+      attrPath = pname;
+    };
+  };
+
+  meta = with lib; {
+    description = "Your little expandable text snippet helper";
+    longDescription = ''
+      Your little expandable text snippet helper.
+
+      Save your often used text snippets and then expand them whenever you type their abbreviation.
+
+      For example:- "spr`" expands to "Snippet Pixie rules!"
+
+      For non-accessible applications such as browsers and Electron apps, there's a shortcut (default is Ctrl+`) for opening a search window that pastes the selected snippet.
+    '';
+    homepage = "https://www.snippetpixie.com";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ ianmjones ] ++ teams.pantheon.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/source-highlight/default.nix b/nixpkgs/pkgs/tools/text/source-highlight/default.nix
new file mode 100644
index 000000000000..8817b7a09fda
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/source-highlight/default.nix
@@ -0,0 +1,53 @@
+{ lib, stdenv, fetchpatch, fetchurl, boost }:
+
+stdenv.mkDerivation rec {
+  pname = "source-highlight";
+  version = "3.1.9";
+
+  src = fetchurl {
+    url = "mirror://gnu/src-highlite/${pname}-${version}.tar.gz";
+    sha256 = "148w47k3zswbxvhg83z38ifi85f9dqcpg7icvvw1cm6bg21x4zrs";
+  };
+
+  patches = [
+    # gcc-11 compat upstream patch
+    (fetchpatch {
+      url = "http://git.savannah.gnu.org/cgit/src-highlite.git/patch/?id=904949c9026cb772dc93fbe0947a252ef47127f4";
+      sha256 = "1wnj0jmkmrwjww7qk9dvfxh8h06jdn7mi8v2fvwh95b6x87z5l47";
+      excludes = [ "ChangeLog" ];
+    })
+  ];
+
+  # source-highlight uses it's own binary to generate documentation.
+  # During cross-compilation, that binary was built for the target
+  # platform architecture, so it can't run on the build host.
+  postPatch = lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
+    substituteInPlace Makefile.in --replace "src doc tests" "src tests"
+  '';
+
+  strictDeps = true;
+  buildInputs = [ boost ];
+
+  configureFlags = [ "--with-boost=${boost.out}" ];
+
+  doCheck = !stdenv.cc.isClang;
+
+  enableParallelBuilding = true;
+  # Upstream uses the same intermediate files in multiple tests, running
+  # them in parallel by make will eventually break one or more tests.
+  enableParallelChecking = false;
+
+  outputs = [ "out" "doc" "dev" ];
+
+  meta = with lib; {
+    description = "Source code renderer with syntax highlighting";
+    longDescription = ''
+      GNU Source-highlight, given a source file, produces a document
+      with syntax highlighting.
+    '';
+    homepage = "https://www.gnu.org/software/src-highlite/";
+    license = licenses.gpl3Plus;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ SuperSandro2000 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/tab/default.nix b/nixpkgs/pkgs/tools/text/tab/default.nix
new file mode 100644
index 000000000000..096e0b04c695
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/tab/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, fetchFromBitbucket, python3 }:
+
+stdenv.mkDerivation rec {
+  version = "8.0";
+  pname = "tab";
+
+  src = fetchFromBitbucket {
+    owner = "tkatchev";
+    repo = pname;
+    rev = version;
+    sha256 = "sha256-RcDvghTiqIdH79khwDIo8PhvmcObmix8WBrHToLwcw4=";
+  };
+
+  checkInputs = [ python3 ];
+
+  doCheck = !stdenv.isDarwin;
+
+  preCheck = ''
+    substituteInPlace Makefile --replace "python2 go2.py" "python go.py"
+  '';
+
+  checkTarget = "test";
+
+  installPhase = ''
+    runHook preInstall
+
+    install -Dm555 -t $out/bin tab
+    install -Dm444 -t $out/share/doc/tab docs/*.html
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "Programming language/shell calculator";
+    homepage    = "https://tkatchev.bitbucket.io/tab/";
+    license     = licenses.boost;
+    maintainers = with maintainers; [ mstarzyk ];
+    platforms   = with platforms; unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/transifex-client/default.nix b/nixpkgs/pkgs/tools/text/transifex-client/default.nix
new file mode 100644
index 000000000000..f1b2928c7941
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/transifex-client/default.nix
@@ -0,0 +1,32 @@
+{ lib, buildPythonApplication, fetchPypi
+, python-slugify, requests, urllib3, six, setuptools, GitPython }:
+
+buildPythonApplication rec {
+  pname = "transifex-client";
+  version = "0.14.3";
+
+  propagatedBuildInputs = [
+    urllib3 requests python-slugify six setuptools GitPython
+  ];
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "sha256-sKol67lRaYPFa7Bg9KNa1rDrNoT9DtUd48NY8jqK1iw=";
+  };
+
+  # https://github.com/transifex/transifex-client/issues/323
+  prePatch = ''
+    substituteInPlace requirements.txt \
+      --replace "python-slugify<5.0.0" "python-slugify"
+  '';
+
+  # Requires external resources
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://www.transifex.com/";
+    license = licenses.gpl2Only;
+    description = "Transifex translation service client";
+    maintainers = with maintainers; [ sikmir ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/tv/default.nix b/nixpkgs/pkgs/tools/text/tv/default.nix
new file mode 100644
index 000000000000..686433ff4290
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/tv/default.nix
@@ -0,0 +1,23 @@
+{ fetchFromGitHub, lib, rustPlatform }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "tv";
+  version = "0.7.0";
+
+  src = fetchFromGitHub {
+    owner = "uzimaru0000";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-qODv45smZ6jHCJBaa6EEvFLG+7g+FWrRf6BiHRFLzqM=";
+  };
+
+  cargoSha256 = "sha256-nI4n4KMPLaIF978b5VvW3mb02vKW+r39nllrhukJilI=";
+
+  meta = with lib; {
+    description = "Format json into table view";
+    homepage = "https://github.com/uzimaru0000/tv";
+    changelog = "https://github.com/uzimaru0000/tv/blob/v${version}/CHANGELOG.md";
+    license = licenses.mit;
+    maintainers = with maintainers; [ figsoda ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/txt2tags/default.nix b/nixpkgs/pkgs/tools/text/txt2tags/default.nix
new file mode 100644
index 000000000000..eb299caade9c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/txt2tags/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchurl, python }:
+
+stdenv.mkDerivation rec {
+  version = "2.6";
+  pname = "txt2tags";
+
+  dontBuild = true;
+
+  # Python script, needs the interpreter
+  propagatedBuildInputs = [ python ];
+
+  installPhase = ''
+    mkdir -p "$out/bin"
+    mkdir -p "$out/share/doc"
+    mkdir -p "$out/share/man/man1/"
+    sed '1s|/usr/bin/env python|${python}/bin/python|' < txt2tags > "$out/bin/txt2tags"
+    chmod +x "$out/bin/txt2tags"
+    gzip - < doc/manpage.man > "$out/share/man/man1/txt2tags.1.gz"
+    cp doc/userguide.pdf "$out/share/doc"
+    cp -r extras/ samples/ test/ "$out/share"
+  '';
+
+  src = fetchurl {
+    url = "http://txt2tags.googlecode.com/files/${pname}-${version}.tgz";
+    sha256 = "0p5hql559pk8v5dlzgm75yrcxwvz4z30f1q590yzng0ghvbnf530";
+  };
+
+  meta = {
+    homepage = "https://txt2tags.org/";
+    description = "A KISS markup language";
+    license  = lib.licenses.gpl2;
+    maintainers = with lib.maintainers; [ kovirobi ];
+    platforms = with lib.platforms; unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/ucg/default.nix b/nixpkgs/pkgs/tools/text/ucg/default.nix
new file mode 100644
index 000000000000..d81b5a14f091
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ucg/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv
+, fetchFromGitHub
+, pkg-config
+, autoreconfHook
+, pcre
+, nixosTests
+}:
+
+let
+  pname = "ucg";
+  version = "20190225";
+in stdenv.mkDerivation {
+  inherit pname version;
+
+  src = fetchFromGitHub {
+    owner = "gvansickle";
+    repo = pname;
+    rev = "c3a67632f1e3f332bfb102f0db167f34a2e42da7";
+    sha256 = "sha256-/wU1PmI4ejlv7gZzZNasgROYXFiDiIxE9BFoCo6+G5Y=";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkg-config ];
+  buildInputs = [ pcre ];
+
+  meta = with lib; {
+    homepage = "https://github.com/gvansickle/ucg/";
+    description = "Grep-like tool for searching large bodies of source code";
+    longDescription = ''
+      UniversalCodeGrep (ucg) is an extremely fast grep-like tool specialized
+      for searching large bodies of source code. It is intended to be largely
+      command-line compatible with Ack, to some extent with ag, and where
+      appropriate with grep. Search patterns are specified as PCRE regexes.
+    '';
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ AndersonTorres ];
+    platforms = with platforms; unix;
+  };
+
+  passthru.tests = { inherit (nixosTests) ucg; };
+}
diff --git a/nixpkgs/pkgs/tools/text/ugrep/default.nix b/nixpkgs/pkgs/tools/text/ugrep/default.nix
new file mode 100644
index 000000000000..2a00ba055725
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/ugrep/default.nix
@@ -0,0 +1,39 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, boost
+, bzip2
+, lz4
+, pcre2
+, xz
+, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "ugrep";
+  version = "3.3.7";
+
+  src = fetchFromGitHub {
+    owner = "Genivia";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-FnSOurICD4n2Z/snP0ysWZ30DnyEDZMqpjRrS1WxG+Q=";
+  };
+
+  buildInputs = [
+    boost
+    bzip2
+    lz4
+    pcre2
+    xz
+    zlib
+  ];
+
+  meta = with lib; {
+    description = "Ultra fast grep with interactive query UI";
+    homepage = "https://github.com/Genivia/ugrep";
+    maintainers = with maintainers; [ numkem ];
+    license = licenses.bsd3;
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/uni2ascii/default.nix b/nixpkgs/pkgs/tools/text/uni2ascii/default.nix
new file mode 100644
index 000000000000..d83e9393f941
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/uni2ascii/default.nix
@@ -0,0 +1,41 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "uni2ascii";
+  version = "4.18";
+
+  src = fetchurl {
+    url = "https://billposer.org/Software/Downloads/uni2ascii-${version}.tar.gz";
+    sha256 = "03lklnzr6ngs4wqiqa7rifd246f441gfvardbsaa5l6fn9pbn94y";
+  };
+
+  meta = {
+    license = lib.licenses.gpl3;
+    homepage = "http://billposer.org/Software/uni2ascii.html";
+    description = "Converts between UTF-8 and many 7-bit ASCII equivalents and back";
+
+    longDescription = ''
+    This package provides conversion in both directions between UTF-8
+    Unicode and more than thirty 7-bit ASCII equivalents, including
+    RFC 2396 URI format and RFC 2045 Quoted Printable format, the
+    representations used in HTML, SGML, XML, OOXML, the Unicode
+    standard, Rich Text Format, POSIX portable charmaps, POSIX locale
+    specifications, and Apache log files, and the escapes used for
+    including Unicode in Ada, C, Common Lisp, Java, Pascal, Perl,
+    Postscript, Python, Scheme, and Tcl.
+
+    Such ASCII equivalents are useful when including Unicode text in
+    program source, when debugging, and when entering text into web
+    programs that can handle the Unicode character set but are not
+    8-bit safe. For example, MovableType, the blog software, truncates
+    posts as soon as it encounters a byte with the high bit
+    set. However, if Unicode is entered in the form of HTML numeric
+    character entities, Movable Type will not garble the post.
+
+    It also provides ways of converting non-ASCII characters to
+    similar ASCII characters, e.g. by stripping diacritics.
+    '';
+    maintainers = with lib.maintainers; [ goibhniu ];
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/unoconv/default.nix b/nixpkgs/pkgs/tools/text/unoconv/default.nix
new file mode 100644
index 000000000000..4516eba5095f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/unoconv/default.nix
@@ -0,0 +1,41 @@
+{ lib, stdenv, fetchFromGitHub, python3, libreoffice-unwrapped, asciidoc, makeWrapper
+# whether to install odt2pdf/odt2doc/... symlinks to unoconv
+, installSymlinks ? true
+}:
+
+# IMPORTANT: unoconv must use the same python version as libreoffice (unless it
+# will not be able to load the pyuno module from libreoffice).
+
+stdenv.mkDerivation rec {
+  pname = "unoconv";
+  version = "0.9.0";
+
+  src = fetchFromGitHub {
+    owner = "unoconv";
+    repo = "unoconv";
+    rev = version;
+    sha256 = "1akx64686in8j8arl6vsgp2n3bv770q48pfv283c6fz6wf9p8fvr";
+  };
+
+  nativeBuildInputs = [ asciidoc makeWrapper ];
+
+  preBuild = ''
+    makeFlags=prefix="$out"
+  '';
+
+  postInstall = ''
+    sed -i "s|/usr/bin/env python.*|${python3}/bin/${python3.executable}|" "$out/bin/unoconv"
+    wrapProgram "$out/bin/unoconv" \
+       --set-default UNO_PATH ${libreoffice-unwrapped}/lib/libreoffice/program/
+  '' + (if installSymlinks then ''
+    make install-links prefix="$out"
+  '' else "");
+
+  meta = with lib; {
+    description = "Convert between any document format supported by LibreOffice/OpenOffice";
+    homepage = "http://dag.wieers.com/home-made/unoconv/";
+    license = licenses.gpl2;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/unrtf/default.nix b/nixpkgs/pkgs/tools/text/unrtf/default.nix
new file mode 100644
index 000000000000..3357404a7d3c
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/unrtf/default.nix
@@ -0,0 +1,31 @@
+{ lib, stdenv, fetchurl, autoconf, automake, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "unrtf";
+  version = "0.21.10";
+
+  src = fetchurl {
+    url = "https://ftp.gnu.org/gnu/${pname}/${pname}-${version}.tar.gz";
+    sha256 = "1bil6z4niydz9gqm2j861dkxmqnpc8m7hvidsjbzz7x63whj17xl";
+  };
+
+  nativeBuildInputs = [ autoconf automake ];
+
+  buildInputs = [ libiconv ];
+
+  preConfigure = "./bootstrap";
+
+  outputs = [ "out" "man" ];
+
+  meta = with lib; {
+    description = "A converter from Rich Text Format to other formats";
+    longDescription = ''
+      UnRTF converts documents in Rich Text Format to other
+      formats, including HTML, LaTeX, and RTF itself.
+    '';
+    homepage = "https://www.gnu.org/software/unrtf/";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ joachifm ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/untex/default.nix b/nixpkgs/pkgs/tools/text/untex/default.nix
new file mode 100644
index 000000000000..55cf01d698f8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/untex/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "untex";
+  version = "1.3";
+
+  src = fetchurl {
+    url = "ftp://ftp.thp.uni-duisburg.de/pub/source/${pname}-${version}.tar.gz";
+    sha256 = "1jww43pl9qvg6kwh4h8imp966fzd62dk99pb4s93786lmp3kgdjv";
+  };
+
+  hardeningDisable = [ "format" ];
+
+  unpackPhase = "tar xf $src";
+  installTargets = [ "install" "install.man" ];
+  installFlags = [ "BINDIR=$(out)/bin" "MANDIR=$(out)/share/man/man1" ];
+  preBuild = ''
+    sed -i '1i#include <stdlib.h>\n#include <string.h>' untex.c
+    mkdir -p $out/bin $out/share/man/man1
+  '';
+
+  meta = with lib; {
+    description = "A utility which removes LaTeX commands from input";
+    homepage = "https://www.ctan.org/pkg/untex";
+    license = licenses.gpl1;
+    maintainers = with maintainers; [ joachifm ];
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/uwc/default.nix b/nixpkgs/pkgs/tools/text/uwc/default.nix
new file mode 100644
index 000000000000..14fe74723a3b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/uwc/default.nix
@@ -0,0 +1,24 @@
+{ rustPlatform, lib, fetchFromGitLab }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "uwc";
+  version = "1.0.4";
+
+  src = fetchFromGitLab {
+    owner = "dead10ck";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "1ywqq9hrrm3frvd2sswknxygjlxi195kcy7g7phwq63j7hkyrn50";
+  };
+
+  cargoSha256 = "04pslga3ff766cpb73n6ivzmqfa0hm19gcla8iyv6p59ddsajh3q";
+
+  doCheck = true;
+
+  meta = with lib; {
+    description = "Like wc, but unicode-aware, and with per-line mode";
+    homepage = "https://gitlab.com/dead10ck/uwc";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ShamrockLee ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/vale/default.nix b/nixpkgs/pkgs/tools/text/vale/default.nix
new file mode 100644
index 000000000000..25a98d299a75
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/vale/default.nix
@@ -0,0 +1,32 @@
+{ lib, buildGoModule, fetchFromGitHub }:
+
+buildGoModule rec {
+  pname = "vale";
+  version = "2.10.6";
+
+  subPackages = [ "cmd/vale" ];
+  outputs = [ "out" "data" ];
+
+  src = fetchFromGitHub {
+    owner  = "errata-ai";
+    repo   = "vale";
+    rev    = "v${version}";
+    sha256 = "sha256-exBrs/MQhfqCxAJrnxECdKnxvsK9LvXIqpnYkR5h7uA=";
+  };
+
+  vendorSha256 = "sha256-3rCrRA9OKG2/wUlVvkG9lynJZOYFVqMkUZpGpW89KZc=";
+
+  postInstall = ''
+    mkdir -p $data/share/vale
+    cp -r styles $data/share/vale
+  '';
+
+  ldflags = [ "-s" "-w" "-X main.version=${version}" ];
+
+  meta = with lib; {
+    homepage = "https://docs.errata.ai/vale/about";
+    description = "A syntax-aware linter for prose built with speed and extensibility in mind";
+    license = licenses.mit;
+    maintainers = [ maintainers.marsam ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/vgrep/default.nix b/nixpkgs/pkgs/tools/text/vgrep/default.nix
new file mode 100644
index 000000000000..1eea8b7f67b3
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/vgrep/default.nix
@@ -0,0 +1,32 @@
+{ lib, buildGoModule, fetchFromGitHub, go-md2man, installShellFiles }:
+
+buildGoModule rec {
+  pname = "vgrep";
+  version = "2.5.1";
+
+  src = fetchFromGitHub {
+    owner = "vrothberg";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "06rnmg6ljj4f1g602wdp2wy9v0m1m0sj6jl6wywyjl8grjqc3vac";
+  };
+
+  vendorSha256 = null;
+
+  ldflags = [ "-s" "-w" "-X main.version=${version}" ];
+
+  nativeBuildInputs = [ go-md2man installShellFiles ];
+
+  postBuild = ''
+    sed -i '/SHELL= /d' Makefile
+    make docs
+    installManPage docs/*.[1-9]
+  '';
+
+  meta = with lib; {
+    description = "User-friendly pager for grep/git-grep/ripgrep";
+    homepage = "https://github.com/vrothberg/vgrep";
+    license = licenses.gpl3Only;
+    maintainers = with maintainers; [ SuperSandro2000 ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/wdiff/default.nix b/nixpkgs/pkgs/tools/text/wdiff/default.nix
new file mode 100644
index 000000000000..510cf18369e6
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/wdiff/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, texinfo, which }:
+
+stdenv.mkDerivation rec {
+  pname = "wdiff";
+  version = "1.2.2";
+
+  src = fetchurl {
+    url = "mirror://gnu/wdiff/${pname}-${version}.tar.gz";
+    sha256 = "0sxgg0ms5lhi4aqqvz1rj4s77yi9wymfm3l3gbjfd1qchy66kzrl";
+  };
+
+  # for makeinfo
+  nativeBuildInputs = [ texinfo ];
+
+  buildInputs = [ texinfo ];
+
+  checkInputs = [ which ];
+
+  strictDeps = true;
+
+  meta = with lib; {
+    homepage = "https://www.gnu.org/software/wdiff/";
+    description = "Comparing files on a word by word basis";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ eelco SuperSandro2000 ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/wgetpaste/default.nix b/nixpkgs/pkgs/tools/text/wgetpaste/default.nix
new file mode 100644
index 000000000000..a3a7a8bd54ac
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/wgetpaste/default.nix
@@ -0,0 +1,30 @@
+{ lib, stdenv, fetchurl, wget, bash }:
+
+stdenv.mkDerivation rec {
+  version = "2.30";
+  pname = "wgetpaste";
+
+  src = fetchurl {
+    url = "http://wgetpaste.zlin.dk/${pname}-${version}.tar.bz2";
+    sha256 = "14k5i6j6f34hcf9gdb9cnvfwscn0ys2dgd73ci421wj9zzqkbv73";
+  };
+  # currently zsh-autocompletion support is not installed
+
+  prePatch = ''
+    substituteInPlace wgetpaste --replace "/usr/bin/env bash" "${bash}/bin/bash"
+    substituteInPlace wgetpaste --replace "LC_ALL=C wget" "LC_ALL=C ${wget}/bin/wget"
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin;
+    cp wgetpaste $out/bin;
+  '';
+
+  meta = {
+    description = "Command-line interface to various pastebins";
+    homepage = "http://wgetpaste.zlin.dk/";
+    license = lib.licenses.publicDomain;
+    maintainers = with lib.maintainers; [ qknight domenkozar ];
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/wrap/default.nix b/nixpkgs/pkgs/tools/text/wrap/default.nix
new file mode 100644
index 000000000000..e228f946a8c8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/wrap/default.nix
@@ -0,0 +1,36 @@
+{ lib, buildGoModule, fetchFromGitHub, fetchpatch, makeWrapper, courier-prime }:
+
+buildGoModule rec {
+  pname = "wrap";
+  version = "0.3.1";
+
+  src = fetchFromGitHub {
+    owner = "Wraparound";
+    repo = "wrap";
+    rev = "v${version}";
+    sha256 = "0scf7v83p40r9k7k5v41rwiy9yyanfv3jm6jxs9bspxpywgjrk77";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  vendorSha256 = "03q5a5lm8zj1523gxkbc0y6a3mjj1z2h7nrr2qcz8nlghvp4cfaz";
+
+  patches = [
+    (fetchpatch {
+      name = "courier-prime-variants.patch";
+      url = "https://github.com/Wraparound/wrap/commit/b72c280b6eddba9ec7b3507c1f143eb28a85c9c1.patch";
+      sha256 = "1d9v0agfd7mgd17k4a8l6vr2kyswyfsyq3933dz56pgs5d3jric5";
+    })
+  ];
+
+  postInstall = ''
+    wrapProgram $out/bin/wrap --prefix XDG_DATA_DIRS : ${courier-prime}/share/
+  '';
+
+  meta = with lib; {
+    description = "A Fountain export tool with some extras";
+    homepage = "https://github.com/Wraparound/wrap";
+    license = licenses.gpl3Only;
+    maintainers = [ maintainers.austinbutler ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xidel/default.nix b/nixpkgs/pkgs/tools/text/xidel/default.nix
new file mode 100644
index 000000000000..97c74e370089
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xidel/default.nix
@@ -0,0 +1,93 @@
+{ lib, stdenv, fetchsvn, fetchFromGitHub, fpc }:
+
+let
+  flreSrc = fetchFromGitHub {
+    owner = "benibela";
+    repo = "flre";
+    rev = "5aa8a9e032feff7a5790104f2d53fa74c70bb1d9"; # latest as of 0.9.8 release date
+    sha256 = "1zny494jm92fjgfirzwmxff988j4yygblaxmaclkkmcvzkjrzs05";
+  };
+  synapseSrc = fetchsvn {
+    url = "http://svn.code.sf.net/p/synalist/code/synapse/40/";
+    rev = 237;
+    sha256 = "0ciqd2xgpinwrk42cpyinh9gz2i5s5rlww4mdlsca1h6saivji96";
+  };
+  rcmdlineSrc = fetchFromGitHub {
+    owner = "benibela";
+    repo = "rcmdline";
+    rev = "96859e574e82d76eae49d5552a8c5aa7574a5987"; # latest as of 0.9.8 release date
+    sha256 = "0vwvpwrxsy9axicbck143yfxxrdifc026pv9c2lzqxzskf9fd78b";
+  };
+  internettoolsSrc = fetchFromGitHub {
+    owner = "benibela";
+    repo = "internettools";
+    rev = "c9c5cc3a87271180d4fb5bb0b17040763d2cfe06"; # latest as of 0.9.8 release date
+    sha256 = "057hn7cb1vy827gvim3b6vwgfdh2ckjy8h9yj1ry7lv6hw8ynx6n";
+  };
+in stdenv.mkDerivation rec {
+  pname = "xidel";
+  version = "0.9.8";
+
+  src = fetchFromGitHub {
+    owner = "benibela";
+    repo = pname;
+    rev = "Xidel_${version}";
+    sha256 = "0q75jjyciybvj6y17s2283zis9fcw8w5pfsq8bn7diinnbjnzgl6";
+  };
+
+  nativeBuildInputs = [ fpc ];
+
+  patchPhase = ''
+    patchShebangs \
+      build.sh \
+      tests/test.sh \
+      tests/tests-file-module.sh \
+      tests/tests.sh \
+      tests/downloadTest.sh \
+      tests/downloadTests.sh \
+      tests/zorbajsoniq.sh \
+      tests/zorbajsoniq/download.sh
+  '';
+
+  preBuildPhase = ''
+    mkdir -p import/{flre,synapse} rcmdline internettools
+    cp -R ${flreSrc}/. import/flre
+    cp -R ${synapseSrc}/. import/synapse
+    cp -R ${rcmdlineSrc}/. rcmdline
+    cp -R ${internettoolsSrc}/. internettools
+  '';
+
+  buildPhase = ''
+    runHook preBuildPhase
+    ./build.sh
+    runHook postBuildPhase
+  '';
+
+  installPhase = ''
+    mkdir -p "$out/bin" "$out/share/man/man1"
+    cp meta/xidel.1 "$out/share/man/man1/"
+    cp xidel "$out/bin/"
+  '';
+
+  doCheck = true;
+
+  checkPhase = ''
+    # Not all, if any, of these tests are blockers. Failing or not this phase will pass.
+    # As of 2021-08-15, all of 37 failed tests are linked with the lack of network access.
+    ./tests/tests.sh
+  '';
+
+  doInstallCheck = true;
+
+  installCheckPhase = ''
+    $out/bin/xidel --version | grep "${version}"
+  '';
+
+  meta = with lib; {
+    description = "Command line tool to download and extract data from HTML/XML pages as well as JSON APIs";
+    homepage = "https://www.videlibri.de/xidel.html";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/basex/basex.svg b/nixpkgs/pkgs/tools/text/xml/basex/basex.svg
new file mode 100644
index 000000000000..9d476cec2ca1
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/basex/basex.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2178"
+   sodipodi:version="0.32"
+   inkscape:version="0.45"
+   width="1568"
+   height="1164"
+   version="1.0"
+   sodipodi:docbase="F:\Uni\Scholl\Research\Conferences\BTW2007\Poster"
+   sodipodi:docname="Logo.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   sodipodi:modified="true">
+  <metadata
+     id="metadata2183">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs2181" />
+  <sodipodi:namedview
+     inkscape:window-height="1150"
+     inkscape:window-width="1143"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.64948454"
+     inkscape:cx="784"
+     inkscape:cy="584.00852"
+     inkscape:window-x="412"
+     inkscape:window-y="20"
+     inkscape:current-layer="layer2"
+     showgrid="false"
+     inkscape:object-bbox="true"
+     inkscape:object-points="true"
+     gridempspacing="10" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     style="opacity:1">
+    <path
+       style="font-size:1470px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:19.98425102;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;font-family:Clarendo"
+       d="M 628.08008,847.55762 C 613.24569,864.30587 601.88095,879.3791 593.98584,892.77734 C 586.08995,906.17595 582.1422,916.94254 582.14258,925.07715 C 582.1422,937.9972 586.92735,947.08899 596.49805,952.35254 C 606.06796,957.61633 624.49079,960.24816 651.7666,960.24805 L 720.67285,960.24805 L 720.67285,1072.2207 L 207.46484,1072.2207 L 207.46484,960.24805 L 256.27344,960.24805 C 284.9843,960.24816 308.07265,955.94152 325.53857,947.32813 C 343.00426,938.71498 364.89633,919.09586 391.21484,888.4707 L 673.2998,568.34375 L 441.45898,276.92773 C 416.57596,245.82505 393.60723,224.77038 372.55273,213.76367 C 351.4979,202.75868 325.89734,197.25576 295.75098,197.25488 L 245.50684,197.25488 L 245.50684,86 L 767.32813,86 L 767.32813,197.25488 L 699.85742,197.25488 C 685.97999,197.25576 675.45266,199.76796 668.27539,204.7915 C 661.0972,209.81678 657.50834,217.11414 657.50879,226.68359 C 657.50834,233.38365 659.30277,240.20249 662.89209,247.14014 C 666.4805,254.07943 672.58156,262.57308 681.19531,272.62109 L 810.39453,429.81348 L 967.58691,265.44336 C 974.76388,258.26644 980.50606,250.84945 984.81348,243.19238 C 989.11933,235.53697 991.27265,229.07702 991.27344,223.8125 C 991.27265,215.20008 985.88936,208.62049 975.12354,204.07373 C 964.35618,199.5287 948.20629,197.25576 926.67383,197.25488 L 869.25195,197.25488 L 869.25195,86 L 1332.2158,86 L 1332.2158,197.25488 L 1279.1006,197.25488 C 1241.2968,197.25576 1189.8564,233.14439 1124.7793,304.9209 L 1123.3438,306.35645 L 905.8584,544.65723 L 1155.6436,856.1709 C 1194.8808,904.97966 1224.6684,934.52797 1245.0063,944.81592 C 1265.3422,955.10412 1294.412,960.24816 1332.2158,960.24805 L 1376,960.24805 L 1376,1072.2207 L 810.39453,1072.2207 L 810.39453,960.24805 L 877.86523,960.24805 C 901.79032,960.24816 919.25612,958.21447 930.2627,954.14697 C 941.26782,950.07971 946.77074,943.26087 946.77148,933.69043 C 946.77074,926.51284 945.3352,918.97623 942.46484,911.08057 C 939.59302,903.18523 935.28638,895.64861 929.54492,888.4707 L 768.76367,685.34082 L 628.08008,847.55762 z "
+       id="text2175" />
+    <path
+       style="font-size:500px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#e00000;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;font-family:Arial Black"
+       d="M 146.16714,395.52869 L 353.19839,395.52869 C 387.70332,395.52904 414.19255,404.07396 432.66616,421.16345 C 451.13913,438.25361 460.37577,459.41244 460.37612,484.64001 C 460.37577,505.79912 453.78398,523.94688 440.60073,539.08337 C 431.81135,549.17472 418.95329,557.14998 402.02651,563.00916 C 427.74234,569.19424 446.66322,579.81434 458.78921,594.86951 C 470.9145,609.92499 476.97732,628.84587 476.97768,651.6322 C 476.97732,670.18697 472.66417,686.8699 464.03823,701.68103 C 455.41158,716.49227 443.61146,728.211 428.63784,736.83728 C 419.36019,742.20839 405.3628,746.11463 386.64565,748.55603 C 361.74306,751.81124 345.22289,753.43884 337.08511,753.43884 L 146.16714,753.43884 L 146.16714,395.52869 z M 257.7394,535.90955 L 305.83511,535.90955 C 323.0875,535.90976 335.09107,532.93939 341.84585,526.99841 C 348.60017,521.05789 351.97744,512.47229 351.97768,501.24158 C 351.97744,490.82517 348.60017,482.68716 341.84585,476.82751 C 335.09107,470.96842 323.33164,468.03874 306.56753,468.03845 L 257.7394,468.03845 L 257.7394,535.90955 z M 257.7394,676.53455 L 314.13589,676.53455 C 333.17863,676.53462 346.60635,673.15735 354.41909,666.40271 C 362.23134,659.64825 366.13758,650.57436 366.13784,639.18103 C 366.13758,628.60173 362.27203,620.0975 354.54116,613.66833 C 346.8098,607.23944 333.26001,604.02493 313.89175,604.02478 L 257.7394,604.02478 L 257.7394,676.53455 z "
+       id="text2205" />
+    <path
+       style="font-size:500px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#e00000;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;font-family:Arial Black"
+       d="M 703.69272,694.35681 L 577.71616,694.35681 L 560.38217,753.43884 L 447.34506,753.43884 L 581.86655,395.52869 L 702.47202,395.52869 L 836.9935,753.43884 L 721.27084,753.43884 L 703.69272,694.35681 z M 680.49936,616.96423 L 640.94858,488.30212 L 601.64194,616.96423 L 680.49936,616.96423 z "
+       id="text3180" />
+    <path
+       style="font-size:500px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#e00000;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;font-family:Arial Black"
+       d="M 810.90509,641.13416 L 916.1297,634.54236 C 918.40822,651.63231 923.04689,664.65313 930.04572,673.60486 C 941.4388,688.09061 957.71482,695.33344 978.87384,695.33337 C 994.6614,695.33344 1006.8277,691.63064 1015.3729,684.22498 C 1023.9176,676.81946 1028.19,668.23386 1028.1902,658.46814 C 1028.19,649.19091 1024.121,640.89013 1015.9832,633.5658 C 1007.845,626.24171 988.96479,619.3244 959.34259,612.81384 C 910.83987,601.90905 876.25331,587.42339 855.58282,569.35681 C 834.74945,551.29061 824.33279,528.26004 824.33282,500.26501 C 824.33279,481.87337 829.66319,464.49871 840.32404,448.14099 C 850.98479,431.7839 867.01667,418.92584 888.41974,409.56677 C 909.82262,400.20841 939.16015,395.52905 976.43243,395.52869 C 1022.1679,395.52905 1057.0393,404.03327 1081.0467,421.04138 C 1105.0535,438.05017 1119.3358,465.10906 1123.8934,502.21814 L 1019.6453,508.32166 C 1016.8782,492.20864 1011.0595,480.4899 1002.1893,473.16541 C 993.31863,465.84148 981.07092,462.17937 965.44611,462.17908 C 952.58787,462.17937 942.90364,464.90561 936.39337,470.35779 C 929.88282,475.81055 926.62761,482.44303 926.62775,490.25525 C 926.62761,495.95213 929.31316,501.07908 934.68439,505.63611 C 939.89257,510.35641 952.26235,514.75094 971.79376,518.8197 C 1020.1334,529.2366 1054.7606,539.77533 1075.6756,550.43591 C 1096.59,561.09692 1111.8081,574.32119 1121.3299,590.10876 C 1130.851,605.89668 1135.6118,623.55617 1135.6121,643.08728 C 1135.6118,666.03659 1129.2641,687.19543 1116.5692,706.56384 C 1103.8735,725.93237 1086.1327,740.62148 1063.3465,750.63123 C 1040.5598,760.64099 1011.8326,765.64587 977.16486,765.64587 C 916.29234,765.64587 874.13743,753.92713 850.70001,730.48962 C 827.26248,707.05218 813.99752,677.26705 810.90509,641.13416 L 810.90509,641.13416 z "
+       id="text3184" />
+    <path
+       style="font-size:500px;font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#e00000;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;font-family:Arial Black"
+       d="M 1139.0592,395.52869 L 1435.4459,395.52869 L 1435.4459,471.9447 L 1249.899,471.9447 L 1249.899,528.82947 L 1422.0182,528.82947 L 1422.0182,601.82751 L 1249.899,601.82751 L 1249.899,672.38416 L 1440.817,672.38416 L 1440.817,753.43884 L 1139.0592,753.43884 L 1139.0592,395.52869 z "
+       id="text3188" />
+  </g>
+</svg>
diff --git a/nixpkgs/pkgs/tools/text/xml/basex/default.nix b/nixpkgs/pkgs/tools/text/xml/basex/default.nix
new file mode 100644
index 000000000000..0e2c8b824f5e
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/basex/default.nix
@@ -0,0 +1,66 @@
+{ lib, stdenv, fetchurl, unzip, jre, coreutils, makeDesktopItem }:
+
+stdenv.mkDerivation rec {
+  pname = "basex";
+  version = "9.4.3";
+
+  src = fetchurl {
+    url = "http://files.basex.org/releases/${version}/BaseX${builtins.replaceStrings ["."] [""] version}.zip";
+    hash = "sha256-IZhRg2JcYQXQKU/lYZpLLcsSdjZZO+toY5yvk+RKUCY=";
+  };
+
+  nativeBuildInputs = [ unzip ];
+  buildInputs = [ jre ];
+
+  desktopItem = makeDesktopItem {
+    name = "basex";
+    exec = "basexgui %f";
+    icon = "${./basex.svg}"; # icon copied from Ubuntu basex package
+    comment = "Visually query and analyse your XML data";
+    desktopName = "BaseX XML Database";
+    genericName = "XML database tool";
+    categories = "Development;Utility;Database";
+    mimeType = "text/xml";
+  };
+
+  dontBuild = true;
+
+  installPhase = ''
+    # Remove Windows batch files (unclutter $out/bin)
+    rm ./bin/*.bat
+
+    mkdir -p "$out/share/basex" "$out/share/applications"
+
+    cp -R bin etc lib webapp src BaseX.jar "$out"
+    cp -R readme.txt webapp "$out/share/basex"
+
+    # Install desktop file
+    cp "$desktopItem"/share/applications/* "$out/share/applications/"
+
+    # Use substitutions instead of wrapper scripts
+    for file in "$out"/bin/*; do
+        sed -i -e "s|/usr/bin/env bash|${stdenv.shell}|" \
+               -e "s|java|${jre}/bin/java|" \
+               -e "s|readlink|${coreutils}/bin/readlink|" \
+               -e "s|dirname|${coreutils}/bin/dirname|" \
+               -e "s|basename|${coreutils}/bin/basename|" \
+               -e "s|echo|${coreutils}/bin/echo|" \
+            "$file"
+    done
+  '';
+
+  meta = with lib; {
+    description = "XML database and XPath/XQuery processor";
+    longDescription = ''
+      BaseX is a very fast and light-weight, yet powerful XML database and
+      XPath/XQuery processor, including support for the latest W3C Full Text
+      and Update Recommendations. It supports large XML instances and offers a
+      highly interactive front-end (basexgui). Apart from two local standalone
+      modes, BaseX offers a client/server architecture.
+    '';
+    homepage = "https://basex.org/";
+    license = licenses.bsd3;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/html-xml-utils/default.nix b/nixpkgs/pkgs/tools/text/xml/html-xml-utils/default.nix
new file mode 100644
index 000000000000..96aa01abe6dd
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/html-xml-utils/default.nix
@@ -0,0 +1,20 @@
+{ lib, stdenv, fetchurl, curl, libiconv }:
+
+stdenv.mkDerivation rec {
+  pname = "html-xml-utils";
+  version = "8.0";
+
+  src = fetchurl {
+    url = "https://www.w3.org/Tools/HTML-XML-utils/${pname}-${version}.tar.gz";
+    sha256 = "sha256-dJBZkGwzHCx/us7uAkZiRaI3uRvUCN/485bQc0oGCuI=";
+  };
+
+  buildInputs = [curl libiconv];
+
+  meta = with lib; {
+    description = "Utilities for manipulating HTML and XML files";
+    homepage = "http://www.w3.org/Tools/HTML-XML-utils/";
+    license = licenses.w3c;
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/jing-trang/default.nix b/nixpkgs/pkgs/tools/text/xml/jing-trang/default.nix
new file mode 100644
index 000000000000..542a4709efeb
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/jing-trang/default.nix
@@ -0,0 +1,43 @@
+{ lib, stdenv, fetchFromGitHub, jre_headless, jdk, ant, saxon }:
+
+stdenv.mkDerivation {
+  pname = "jing-trang";
+  version = "20151127";
+
+  src = fetchFromGitHub {
+    owner = "relaxng";
+    repo = "jing-trang";
+    rev = "47a0cbdaec2d48824b78a1c19879ac7875509598"; # needed to compile with jdk8
+    sha256 = "1hhn52z9mv1x9nyvyqnmzg5yrs2lzm9xac7i15izppv02wp32qha";
+  };
+
+  buildInputs = [ jdk ant saxon ];
+
+  CLASSPATH = "lib/saxon.jar";
+
+  preBuild = "ant";
+
+  installPhase = ''
+    mkdir -p "$out"/{share/java,bin}
+    cp ./build/*.jar "$out/share/java/"
+
+    for tool in jing trang; do
+    cat > "$out/bin/$tool" <<EOF
+    #! $SHELL
+    export JAVA_HOME='${jre_headless}'
+    exec '${jre_headless}/bin/java' -jar '$out/share/java/$tool.jar' "\$@"
+    EOF
+    done
+
+    chmod +x "$out"/bin/*
+  '';
+
+  meta = with lib; {
+    description = "A RELAX NG validator in Java";
+    # The homepage is www.thaiopensource.com, but it links to googlecode.com
+    # for downloads and call it the "project site".
+    homepage = "https://www.thaiopensource.com/relaxng/trang.html";
+    platforms = platforms.unix;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/rnv/default.nix b/nixpkgs/pkgs/tools/text/xml/rnv/default.nix
new file mode 100644
index 000000000000..1ee3355d1052
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/rnv/default.nix
@@ -0,0 +1,20 @@
+{ lib, stdenv, fetchurl, expat }:
+
+stdenv.mkDerivation rec {
+  pname = "rnv";
+  version = "1.7.11";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/rnv/rnv-${version}.tar.xz";
+    sha256 = "1rlxrkkkp8b5j6lyvnd9z1d85grmwwmdggkxq6yl226nwkqj1faa";
+  };
+
+  buildInputs = [ expat ];
+
+  meta = with lib; {
+    description = "Relax NG Compact Syntax validator";
+    homepage = "http://www.davidashen.net/rnv.html";
+    license = licenses.bsd3;
+    platforms = platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/rxp/default.nix b/nixpkgs/pkgs/tools/text/xml/rxp/default.nix
new file mode 100644
index 000000000000..5940bc6d60f9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/rxp/default.nix
@@ -0,0 +1,18 @@
+{lib, stdenv, fetchurl} :
+
+stdenv.mkDerivation rec {
+  pname = "rxp";
+  version = "1.5.0";
+
+  src = fetchurl {
+    url = "mirror://debian/pool/main/r/rxp/rxp_${version}.orig.tar.gz";
+    sha256 = "0y365r36wzj4xn1dzhb03spxljnrx8vwqbiwnnwz4630129gzpm6";
+  };
+
+  meta = {
+    license = lib.licenses.gpl2Plus;
+    description = "A validating XML parser written in C";
+    homepage = "http://www.cogsci.ed.ac.uk/~richard/rxp.html";
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xml2/default.nix b/nixpkgs/pkgs/tools/text/xml/xml2/default.nix
new file mode 100644
index 000000000000..265ab10e5ac8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xml2/default.nix
@@ -0,0 +1,22 @@
+{ lib, stdenv, fetchurl, pkg-config, libxml2 }:
+
+stdenv.mkDerivation rec {
+  pname = "xml2";
+  version = "0.5";
+
+  src = fetchurl {
+    url = "https://web.archive.org/web/20160427221603/http://download.ofb.net/gale/xml2-${version}.tar.gz";
+    sha256 = "01cps980m99y99cnmvydihga9zh3pvdsqag2fi1n6k2x7rfkl873";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ libxml2 ];
+
+  meta = with lib; {
+    homepage = "https://web.archive.org/web/20160515005047/http://dan.egnor.name:80/xml2";
+    description = "Tools for command line processing of XML, HTML, and CSV";
+    license = licenses.gpl2Plus;
+    platforms = platforms.all;
+    maintainers = [ maintainers.rycee ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xmldiff/default.nix b/nixpkgs/pkgs/tools/text/xml/xmldiff/default.nix
new file mode 100644
index 000000000000..5814435e111b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xmldiff/default.nix
@@ -0,0 +1,41 @@
+{ lib
+, buildPythonApplication
+, fetchFromGitHub
+, lxml
+, six
+}:
+
+buildPythonApplication rec {
+  pname = "xmldiff";
+  version = "2.4";
+
+  src = fetchFromGitHub {
+    owner = "Shoobx";
+    repo = pname;
+    rev = version;
+    hash = "sha256-xqudHYfwOce2C0pcFzId0JDIIC6R5bllmVKsH+CvTdE=";
+  };
+
+  buildInputs = [
+    lxml
+    six
+  ];
+
+  meta = with lib; {
+    homepage = "https://xmldiff.readthedocs.io/en/stable/";
+    description = "A library and command line utility for diffing xml";
+    longDescription = ''
+      xmldiff is a library and a command-line utility for making diffs out of
+      XML. This may seem like something that doesn't need a dedicated utility,
+      but change detection in hierarchical data is very different from change
+      detection in flat data. XML type formats are also not only used for
+      computer readable data, it is also often used as a format for hierarchical
+      data that can be rendered into human readable formats. A traditional diff
+      on such a format would tell you line by line the differences, but this
+      would not be be readable by a human. xmldiff provides tools to make human
+      readable diffs in those situations.
+    '';
+    license = licenses.mit;
+    maintainers = with maintainers; [ AndersonTorres ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xmlformat/default.nix b/nixpkgs/pkgs/tools/text/xml/xmlformat/default.nix
new file mode 100644
index 000000000000..380baa906c27
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xmlformat/default.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, perl }:
+stdenv.mkDerivation rec {
+  pname = "xmlformat";
+  version = "1.04";
+
+  src = fetchurl {
+    url = "http://www.kitebird.com/software/xmlformat/xmlformat-${version}.tar.gz";
+    sha256 = "1vwgzn4ha0az7dx0cyc6dx5nywwrx9gxhyh08mvdcq27wjbh79vi";
+  };
+
+  buildInputs = [ perl ];
+  buildPhase = ''
+    patchShebangs ./xmlformat.pl
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp ./xmlformat.pl $out/bin/xmlformat
+    cp ./LICENSE $out/
+  '';
+
+  meta = {
+    description = "a configurable formatter (or 'pretty-printer') for XML documents";
+    homepage = "http://www.kitebird.com/software/xmlformat/";
+    license = lib.licenses.bsd3;
+    platforms = lib.platforms.all;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xmloscopy/default.nix b/nixpkgs/pkgs/tools/text/xml/xmloscopy/default.nix
new file mode 100644
index 000000000000..c915e2c7fc5b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xmloscopy/default.nix
@@ -0,0 +1,53 @@
+{ stdenv, lib, makeWrapper, dev_only_shellcheck ? null,
+fetchFromGitHub,
+
+fzf, coreutils, libxml2, libxslt, jing, findutils, gnugrep, gnused,
+docbook5
+}:
+stdenv.mkDerivation rec {
+  pname = "xmloscopy";
+  version = "0.1.3";
+
+  nativeBuildInputs = [
+    makeWrapper
+    dev_only_shellcheck
+  ];
+
+  spath = lib.makeBinPath [
+    fzf
+    coreutils
+    libxml2
+    libxslt
+    jing
+    findutils
+    gnugrep
+    gnused
+  ];
+
+  src = fetchFromGitHub {
+    owner = "grahamc";
+    repo = "xmloscopy";
+    rev = "v${version}";
+    sha256 = "06y5bckrmnq7b5ny2hfvlmdws910jw3xbw5nzy3bcpqsccqnjxrc";
+  };
+
+  installPhase = ''
+    sed -i "s/hard to say/v${version}/" ./xmloscopy
+    type -P shellcheck && shellcheck ./xmloscopy
+    chmod +x ./xmloscopy
+    patchShebangs ./xmloscopy
+    mkdir -p $out/bin
+    cp ./xmloscopy $out/bin/
+    wrapProgram $out/bin/xmloscopy \
+      --set RNG "${docbook5}/xml/rng/docbook/docbook.rng" \
+      --set PATH "${spath}"
+  '';
+
+  meta = with lib; {
+    description = "wtf is my docbook broken?";
+    homepage = "https://github.com/grahamc/xmloscopy";
+    license = licenses.mit;
+    platforms = platforms.all;
+    maintainers = with maintainers; [ grahamc ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xmlstarlet/default.nix b/nixpkgs/pkgs/tools/text/xml/xmlstarlet/default.nix
new file mode 100644
index 000000000000..39d53088babf
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xmlstarlet/default.nix
@@ -0,0 +1,34 @@
+{ lib, stdenv, fetchurl, pkg-config, libxml2, libxslt }:
+
+stdenv.mkDerivation rec {
+  pname = "xmlstarlet";
+  version = "1.6.1";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/xmlstar/xmlstarlet-${version}.tar.gz";
+    sha256 = "1jp737nvfcf6wyb54fla868yrr39kcbijijmjpyk4lrpyg23in0m";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ libxml2 libxslt ];
+
+  preConfigure =
+    ''
+      export LIBXSLT_PREFIX=${libxslt.dev}
+      export LIBXML_PREFIX=${libxml2.dev}
+      export LIBXSLT_LIBS=$(pkg-config --libs libxslt libexslt)
+      export LIBXML_LIBS=$(pkg-config --libs libxml-2.0)
+    '';
+
+  postInstall =
+    ''
+      ln -s xml $out/bin/xmlstarlet
+    '';
+
+  meta = {
+    description = "A command line tool for manipulating and querying XML data";
+    homepage = "http://xmlstar.sourceforge.net/";
+    license = lib.licenses.mit;
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xml/xpf/default.nix b/nixpkgs/pkgs/tools/text/xml/xpf/default.nix
new file mode 100644
index 000000000000..ce0813c2ef4a
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xml/xpf/default.nix
@@ -0,0 +1,21 @@
+{lib, stdenv, fetchurl, python2, libxml2}:
+
+assert libxml2.pythonSupport == true;
+
+stdenv.mkDerivation rec {
+  pname = "xpf";
+  version = "0.2";
+
+  src = fetchurl {
+    url = "http://tarballs.nixos.org/xpf-${version}.tar.gz";
+    sha256 = "0ljx91w68rnh4871c0xlq2whlmhqz8dr39wcdczfjjpniqz1fmpz";
+  };
+
+  buildInputs = [ python2 libxml2 ];
+
+  meta = {
+    description = "XML Pipes and Filters - command line tools for manipulating and querying XML data";
+    homepage = "http://www.cs.uu.nl/wiki/bin/view/Martin/XmlPipesAndFilters";
+    platforms = lib.platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xsv/default.nix b/nixpkgs/pkgs/tools/text/xsv/default.nix
new file mode 100644
index 000000000000..303b38d65c2d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xsv/default.nix
@@ -0,0 +1,24 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, Security }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "xsv";
+  version = "0.13.0";
+
+  src = fetchFromGitHub {
+    owner = "BurntSushi";
+    repo = "xsv";
+    rev = version;
+    sha256 = "17v1nw36mrarrd5yv4xd3mpc1d7lvhd5786mqkzyyraf78pjg045";
+  };
+
+  cargoSha256 = "1bh60zgflaa5n914irkr4bpq3m4h2ngcj6bp5xx1qj112dwgvmyb";
+
+  buildInputs = lib.optional stdenv.isDarwin Security;
+
+  meta = with lib; {
+    description = "A fast CSV toolkit written in Rust";
+    homepage = "https://github.com/BurntSushi/xsv";
+    license = with licenses; [ unlicense /* or */ mit ];
+    maintainers = [ maintainers.jgertm ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/xurls/default.nix b/nixpkgs/pkgs/tools/text/xurls/default.nix
new file mode 100644
index 000000000000..774626561c94
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/xurls/default.nix
@@ -0,0 +1,24 @@
+{ buildGoPackage, lib, fetchFromGitHub }:
+
+buildGoPackage rec {
+  version = "2.3.0";
+  pname = "xurls";
+
+  src = fetchFromGitHub {
+    owner = "mvdan";
+    repo = "xurls";
+    rev = "v${version}";
+    sha256 = "sha256-+oWYW7ZigkNS6VADNmVwarIsYyd730RAdDwnNIAYvlA=";
+  };
+
+  goPackagePath = "mvdan.cc/xurls/v2";
+  subPackages = [ "cmd/xurls" ];
+
+  meta = with lib; {
+    description = "Extract urls from text";
+    homepage = "https://github.com/mvdan/xurls";
+    maintainers = with maintainers; [ koral ];
+    platforms = platforms.unix;
+    license = licenses.bsd3;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/yaml-merge/default.nix b/nixpkgs/pkgs/tools/text/yaml-merge/default.nix
new file mode 100644
index 000000000000..e5794b439a53
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/yaml-merge/default.nix
@@ -0,0 +1,29 @@
+{ lib, stdenv, fetchFromGitHub, pythonPackages }:
+
+stdenv.mkDerivation {
+  pname = "yaml-merge";
+  version = "unstable-2016-02-16";
+
+  src = fetchFromGitHub {
+    owner = "abbradar";
+    repo = "yaml-merge";
+    rev = "4eef7b68632d79dec369b4eff5a8c63f995f81dc";
+    sha256 = "0mwda2shk43i6f22l379fcdchmb07fm7nf4i2ii7fk3ihkhb8dgp";
+  };
+
+  pythonPath = with pythonPackages; [ pyyaml ];
+  nativeBuildInputs = [ pythonPackages.wrapPython ];
+
+  installPhase = ''
+    install -Dm755 yaml-merge.py $out/bin/yaml-merge
+    wrapPythonPrograms
+  '';
+
+  meta = with lib; {
+    description = "Merge YAML data files";
+    homepage = "https://github.com/abbradar/yaml-merge";
+    license = licenses.bsd2;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ abbradar ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/zimwriterfs/default.nix b/nixpkgs/pkgs/tools/text/zimwriterfs/default.nix
new file mode 100644
index 000000000000..9a7e495df2b8
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/zimwriterfs/default.nix
@@ -0,0 +1,43 @@
+{ lib, stdenv
+, fetchFromGitHub
+
+, autoconf
+, automake
+, libtool
+, pkg-config
+
+, file
+, icu
+, gumbo
+, xz
+, xapian
+, zimlib
+, zlib
+}:
+
+stdenv.mkDerivation rec {
+  pname = "zimwriterfs";
+  version = "1.0";
+
+  src = fetchFromGitHub {
+    owner = "wikimedia";
+    repo = "openzim";
+    rev = "${pname}-${version}";
+    sha256 = "1vkrrq929a8s3m5rri1lg0l2vd0mc9n2fsb2z1g88k4n4j2l6f19";
+  };
+
+  nativeBuildInputs = [ automake autoconf libtool pkg-config ];
+  buildInputs = [ file icu gumbo xz zimlib zlib xapian ];
+  setSourceRoot = ''
+    sourceRoot=$(echo */zimwriterfs)
+  '';
+  preConfigure = "./autogen.sh";
+
+  meta = {
+    description = "A console tool to create ZIM files";
+    homepage = "http://git.wikimedia.org/log/openzim";
+    maintainers = with lib.maintainers; [ robbinch ];
+    license = lib.licenses.gpl3;
+    platforms = with lib.platforms; [ linux ];
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/zoekt/default.nix b/nixpkgs/pkgs/tools/text/zoekt/default.nix
new file mode 100644
index 000000000000..cb270f69ad1b
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/zoekt/default.nix
@@ -0,0 +1,29 @@
+{ lib
+, buildGoModule
+, fetchFromGitHub
+, git
+}:
+buildGoModule {
+  pname = "zoekt";
+  version = "unstable-2021-03-17";
+
+  src = fetchFromGitHub {
+    owner = "google";
+    repo = "zoekt";
+    rev = "d92b3b80e582e735b2459413ee7d9dbbf294d629";
+    sha256 = "JdORh6bRdHsAYwsmdKY0OUavXfu3HsPQFkQjRBkcMBo=";
+  };
+
+  vendorSha256 = "d+Xvl6fleMO0frP9qr5tZgkzsnH5lPELwmEQEspD22M=";
+
+  checkInputs = [
+    git
+  ];
+
+  meta = with lib; {
+    description = "Fast trigram based code search";
+    homepage = "https://github.com/google/zoekt";
+    license = licenses.asl20;
+    maintainers = teams.determinatesystems.members;
+  };
+}
diff --git a/nixpkgs/pkgs/tools/text/zstxtns-utils/default.nix b/nixpkgs/pkgs/tools/text/zstxtns-utils/default.nix
new file mode 100644
index 000000000000..362f2fca84d9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/text/zstxtns-utils/default.nix
@@ -0,0 +1,39 @@
+{ coreutils
+, fetchurl
+, gnugrep
+, lib
+, makeWrapper
+, moreutils
+, stdenvNoCC
+}:
+
+stdenvNoCC.mkDerivation rec {
+  pname = "zstxtns-utils";
+  version = "0.0.3";
+
+  src = fetchurl {
+    url = "https://ytrizja.de/distfiles/zstxtns-utils-${version}.tar.gz";
+    sha256 = "I/Gm7vHUr29NClYWQ1kwu8HrNZpdLXfE/nutTNoqcdU=";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  installPhase = ''
+    runHook preInstall
+    install -D -t $out/bin zstxtns-merge zstxtns-unmerge
+    runHook postInstall
+  '';
+
+  postInstall = ''
+    wrapProgram $out/bin/zstxtns-merge --set PATH "${lib.makeBinPath [coreutils gnugrep moreutils]}"
+    wrapProgram $out/bin/zstxtns-unmerge --set PATH "${lib.makeBinPath [coreutils gnugrep]}"
+  '';
+
+  meta = with lib; {
+    description = "utilities to deal with text based name service databases";
+    homepage = "https://ytrizja.de/";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ zseri ];
+    platforms = platforms.all;
+  };
+}