[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft-devel] (no subject)
From: |
Werner LEMBERG |
Subject: |
[ft-devel] (no subject) |
Date: |
Mon, 06 Aug 2018 17:38:19 +0200 (CEST) |
Nikhil,
attached you can find an Elisp script in disguise which calls Emacs
with itself. It will do the paragraph formatting after executing
`markify.py' as discussed.
I've commented the script extensively; hopefully, it makes you
understand the Elisp code a little bit :-)
A typical usage would be
for i in `find . -type f -name "*.h"`; do
bash markdown-format.bash $i
done
to convert all specified header files (without creating backup files).
Up to now I've only found a single incorrect paragraph formatting due
to a sloppy @macro definition in the internal header file `ftserv.h':
It provides a bunch of `FT_DEFINE_SERVICEDESCREC*' lines that wouldn't
be output correctly anyway – this has to be undone manually after
running the script.
Please check and report further problems!
Werner
PS: I think we should change *all* comments in the public header files
to use `xxx` and 'xxx' (whatever appropriate) instead of `xxx' for
consistency. I guess we have to do this manually, right?
#! /bin/sh
":"; exec emacs --no-site-file --script "$0" -- "$@" # -*- mode:emacs-lisp -*-
;;; ^^^ The above line makes `bash' execute emacs in batch mode, using
;;; this script as input. Note that the script handles a single
;;; argument only.
;;; markdown-format.bash
;;;
;;; Written 2018 by
;;; Werner Lemberg <address@hidden>
;;;
;;; This code is explicitly placed into the public domain.
;;; The job of this script is to format paragraphs as emitted by
;;; Nikhil Ramakrishnan's `markify.py' script, cf.
;;;
;;; https://github.com/nikramakrishnan/freetype-docs/blob/master/markify.py
;; We don't want backup files.
(setq make-backup-files nil)
(message "Processing file `%s'" (nth 1 argv))
;; Open file.
(find-file (nth 1 argv))
(defun markdown-format-paragraph ()
""
(interactive)
;; Go to beginning of file.
(goto-char (point-min))
;; Set up a block (called a `form' in Elisp speak) with local
;; variables (called `local bindings' in Elisp speak).
(let ((fill-column 78)
start
end)
;; Outer loop: search a comment line that should be formatted.
;; (Note that backslashes must be doubled in Elisp strings.)
(while (re-search-forward "^ \\*\\( \\|$\\)" nil t)
;; Go to the beginning of the current line and remember this
;; position.
(setq start (line-beginning-position))
(setq end start)
(goto-char start)
(message "%s" (line-number-at-pos))
;; Inner loop: collect stuff for formatting, line by line. Stop
;; also if we have
;;
;; * the start of a code block (surrounded by "```"),
;; * a tag (ending in `::'), or
;; * an address@hidden' or address@hidden' section.
;;
;; Since the regexp machine of Emacs doesn't support negative
;; look-ahead assertions, we use two regexps in succession.
;; Both regexps are restricted to the current line; the second
;; one starts searching at the position where the first stops.
;;
;; `\=' matches the current position (`point' in Elisp speak).
(while (and (re-search-forward
"^ \\*\\( \\|$\\)"
(line-end-position)
t)
(not (re-search-forward
"\\= *\\(```\\|[[:alnum:]_-]+
::\\|@order:\\|@sections:\\)"
(line-end-position)
t)))
;; If we were successful, update end position ...
(setq end (line-end-position))
;; ... and advance to the beginning of the next line.
(beginning-of-line 2))
;; Format the collected lines (if there is something to format)
;; and advance to the next line. Before doing so, however, we
;; have to attach a text property to the character at position
;; `end' so that we can find this character after formatting
;; (`end' is simply an integer and doesn't adjust to the new
;; position). Reason is that `fill-individual-paragraphs'
;; doesn't have a sensible return value, but we need a position
;; to continue.
;;
;; We arbitrarily call the property `fill-end'.
(unless (= start end)
(put-text-property end (+ end 1) 'fill-end t)
(fill-individual-paragraphs start end)
(next-single-property-change start 'fill-end)
(beginning-of-line 2))
;; If the current line starts a code block, skip it.
(if (re-search-forward "^ \\* +```" (line-end-position) t)
(re-search-forward "^ \\* +```" nil t))
;; If the current line starts an address@hidden' or address@hidden'
;; section, skip to the next section or to the end of the
;; comment block.
(if (re-search-forward "^ \\* +\\(@order:\\|@sections:\\)"
(line-end-position)
t)
(unless (re-search-forward "^ \\* address@hidden:alnum:]_-]+:" nil
t)
(re-search-forward "^ \\*/" nil t)))
;; Advance to next line.
(beginning-of-line 2))))
(markdown-format-paragraph)
;; Finally, save file.
(save-buffer)
;;; eof
- [ft-devel] (no subject),
Werner LEMBERG <=