Skip to content

dnouri/markdown-table-wrap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

markdown-table-wrap

MELPA Tests melpazoid

Word-wrap GFM (GitHub Flavored Markdown) pipe tables to fit a given character width. Inline markup survives wrapping.

| Feature   | Status | Notes                         |
|-----------|--------|-------------------------------|
| **Auth**  | Done   | OAuth2 with `refresh tokens`  |
| **DB**    | WIP    | PostgreSQL *connection pool*  |

(markdown-table-wrap table-string 36) rewrites this as:

| Feature  | Status | Notes        |
| -------- | ------ | ------------ |
| **Auth** | Done   | OAuth2 with  |
|          |        | `refresh`    |
|          |        | `tokens`     |
|          |        |              |
| **DB**   | WIP    | PostgreSQL   |
|          |        | *connection* |
|          |        | *pool*       |

The wrapped text is meant for readable source editing and round-tripping with markdown-table-wrap-unwrap. It is not a semantic no-op for Markdown renderers: wrapped headers are no longer valid GFM tables, and wrapped body continuation lines and automatic spacer rows are parsed as additional rows. Bold, italic, code, links, images, and strikethrough markers are duplicated on each continuation line. In buffers where markdown-hide-markup conceals syntax characters, column widths can be measured from visible text so that hidden markers do not waste space.

Installation

Install from MELPA:

M-x package-install RET markdown-table-wrap RET

If MELPA is not configured yet, add this to your init file, restart Emacs, and run M-x package-refresh-contents once:

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

If you use the library from your own code, load it with:

(require 'markdown-table-wrap)

If you prefer use-package:

(use-package markdown-table-wrap
  :ensure t)

Manual installation

If you prefer a plain checkout, add the repository to your load-path and require the library:

(add-to-list 'load-path "/path/to/markdown-table-wrap")
(require 'markdown-table-wrap)

Usage

(markdown-table-wrap table-text 60)

Optional arguments:

;; Cap cell height at 3 lines (truncated cells end with "…")
(markdown-table-wrap table-text 60 3)

;; Measure widths from visible text only (for markdown-hide-markup)
(markdown-table-wrap table-text 60 nil t)

;; Suppress automatic empty rows between wrapped data rows
(markdown-table-wrap table-text 60 nil nil t)

Unwrapping and re-wrapping

Wrapped output is optimized for readable source, not for preserving exact GFM table semantics in Markdown-to-HTML renderers.

(markdown-table-wrap
 (markdown-table-wrap-unwrap previously-wrapped) new-width)

Batch rendering

Parse and measure once, render at each width:

(markdown-table-wrap-batch table-text '(40 60 80 120))

Integration example

(defun my-wrap-table-at-point ()
  "Wrap the pipe table at point to fit the window."
  (interactive)
  (save-excursion
    (let* ((beg (progn (re-search-backward "^|" nil t)
                       (line-beginning-position)))
           (end (progn (re-search-forward "^[^|]" nil t)
                       (line-beginning-position)))
           (text (buffer-substring-no-properties beg (1- end)))
           (wrapped (markdown-table-wrap
                     text (window-width)
                     nil                     ; max cell height
                     markdown-hide-markup))) ; t when markup hidden
      (unless (equal wrapped text)
        (delete-region beg (1- end))
        (goto-char beg)
        (insert wrapped)))))

Features

  • Markup-aware: bold, italic, links, code, images, strikethrough
  • Graceful degradation when columns are too narrow for markup
  • Proportional column-width allocation
  • Alignment preservation (:---:, ---:, :---)
  • Cell height cap with ellipsis
  • Unwrap/re-wrap for resizing; batch rendering
  • Code fence awareness
  • Unicode-aware (CJK, combining marks, VS16 emoji)
  • Pure Elisp, no dependencies

API

Primary functions

  • (markdown-table-wrap TEXT WIDTH &optional MAX-CELL-HEIGHT STRIP-MARKUP COMPACT)

    Rewrite a pipe table to fit WIDTH. Returns pipe-table-shaped text for readable source editing and round-tripping with markdown-table-wrap-unwrap, or TEXT unchanged when it already fits. Wrapped headers are no longer valid GFM tables, and wrapped body continuation lines and automatic spacer rows are parsed as additional rows by Markdown renderers. STRIP-MARKUP measures widths from visible text (for markdown-hide-markup). COMPACT suppresses automatic empty rows between wrapped data rows.

  • (markdown-table-wrap-batch TEXT WIDTHS &optional MAX-CELL-HEIGHT STRIP-MARKUP COMPACT)

    Render at each width in WIDTHS. Parses once.

  • (markdown-table-wrap-unwrap TEXT)

    Merge continuation rows back into logical rows when their boundaries remain detectable. Best suited for text known to be produced by markdown-table-wrap.

The package also exposes markdown-table-wrap-parse, markdown-table-wrap-cell, markdown-table-wrap-compute-widths, markdown-table-wrap-strip-markup, markdown-table-wrap-visible-width, and markdown-table-wrap-inside-code-fence-p. See their docstrings for details.

All public functions are pure (except inside-code-fence-p). No defcustom is defined; configuration is passed as arguments.

License

GPL-3.0-or-later

About

Emacs package to word-wrap GFM pipe tables to fit a given character width

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors