freetype-devel
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]