unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* nXML mode indentation
@ 2018-05-05 13:38 N. Raghavendra
  2018-05-08  4:33 ` N. Raghavendra
  0 siblings, 1 reply; 9+ messages in thread
From: N. Raghavendra @ 2018-05-05 13:38 UTC (permalink / raw)
  To: help-gnu-emacs

I request help regarding indentation of text that is directly inside
elements in nXML mode.  Here is an example of the default indentation
provided by the mode:

----------
<para>Let us suppose that the noumena have nothing to do with necessity,
since knowledge of the Categories is a posteriori.  Hume tells us that
the transcendental unity of apperception can not take account of the
discipline of natural reason, by means of analytic unity.</para>
----------

All the lines in the element are indented to the same column.  I would
like to indent the above text as

----------
<para>Let us suppose that the noumena have nothing to do with
  necessity, since knowledge of the Categories is a posteriori.
  Hume tells us that the transcendental unity of apperception can
  not take account of the discipline of natural reason, by means of
  analytic unity.</para>
----------

Here, every line in the element after the first is indented two columns
more than the first line.  (This is in fact the default indentation of
sgml mode, and psgml mode.)

Is there a way to achieve the second style of indentation in nXML mode?

Thanks,

Raghu.

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-05 13:38 nXML mode indentation N. Raghavendra
@ 2018-05-08  4:33 ` N. Raghavendra
  2018-05-08  4:55   ` Yuri Khan
  2018-05-08  8:09   ` N. Raghavendra
  0 siblings, 2 replies; 9+ messages in thread
From: N. Raghavendra @ 2018-05-08  4:33 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-05T19:08:36+05:30, N. Raghavendra wrote:

> I request help regarding indentation of text that is directly inside
> elements in nXML mode.  Here is an example of the default indentation
> provided by the mode:
>
> ----------
> <para>Let us suppose that the noumena have nothing to do with necessity,
> since knowledge of the Categories is a posteriori.  Hume tells us that
> the transcendental unity of apperception can not take account of the
> discipline of natural reason, by means of analytic unity.</para>
> ----------
>
> All the lines in the element are indented to the same column.  I would
> like to indent the above text as
>
> ----------
> <para>Let us suppose that the noumena have nothing to do with
>   necessity, since knowledge of the Categories is a posteriori.
>   Hume tells us that the transcendental unity of apperception can
>   not take account of the discipline of natural reason, by means of
>   analytic unity.</para>
> ----------
>
> Here, every line in the element after the first is indented two columns
> more than the first line.  (This is in fact the default indentation of
> sgml mode, and psgml mode.)
>
> Is there a way to achieve the second style of indentation in nXML
> mode?

I am bumping this in case it went unnoticed.

I am trying to follow the XML style guidelines of the FreeBSD
Documentation Project,

https://www.freebsd.org/doc/en_US.ISO8859-1/books/fdp-primer/writing-style-guide.html#writing-style-indentation

and I would indeed like to use nXML mode.

It looks like `nxml-compute-indent-from-previous-line' in nxml-mode.el
is relevant, but I can't see how to modify or advise it.

Thanks,
Raghu.

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08  4:33 ` N. Raghavendra
@ 2018-05-08  4:55   ` Yuri Khan
  2018-05-08  5:16     ` N. Raghavendra
  2018-05-08  8:09   ` N. Raghavendra
  1 sibling, 1 reply; 9+ messages in thread
From: Yuri Khan @ 2018-05-08  4:55 UTC (permalink / raw)
  To: nyraghu27132, help-gnu-emacs

On Tue, May 8, 2018 at 11:34 AM N. Raghavendra <nyraghu27132@gmail.com>
wrote:

> > I request help regarding indentation of text that is directly inside
> > elements in nXML mode.
> I am trying to follow the XML style guidelines of the FreeBSD
> Documentation Project,


https://www.freebsd.org/doc/en_US.ISO8859-1/books/fdp-primer/writing-style-guide.html#writing-style-indentation

> and I would indeed like to use nXML mode.

> It looks like `nxml-compute-indent-from-previous-line' in nxml-mode.el
> is relevant, but I can't see how to modify or advise it.

I have customized indentation in nXML for XHTML documents. The exact
indentation rules I use are not relevant to your case but here’s how I
activate it.

See the documentation on ‘indent-line-function’ and the source of
‘nxml-indent-line’ for implementation details.

(defun yk-xhtml-indent-line ()
   "Indent the current line suitably for XHTML."
   <my custom indentation rules>)

(defun yk-xhtml-indent--maybe-enable ()
   "Set the current buffer’s indentation function
to `yk-xhtml-indent-line' if the current schema is “html”."
   (pcase (caddr rng-current-schema)
     ("html" (setq-local indent-line-function 'yk-xhtml-indent-line))))

(with-eval-after-load 'nxml-mode
   (add-hook 'nxml-mode-hook 'yk-xhtml-indent--maybe-enable))



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08  4:55   ` Yuri Khan
@ 2018-05-08  5:16     ` N. Raghavendra
  0 siblings, 0 replies; 9+ messages in thread
From: N. Raghavendra @ 2018-05-08  5:16 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-08T04:55:35Z, Yuri Khan wrote:

> I have customized indentation in nXML for XHTML documents. The exact
> indentation rules I use are not relevant to your case but here’s how I
> activate it.
>
> See the documentation on ‘indent-line-function’ and the source of
> ‘nxml-indent-line’ for implementation details.
>
> (defun yk-xhtml-indent-line ()
>    "Indent the current line suitably for XHTML."
>    <my custom indentation rules>)

Thank you for your reply.

Yes, I had thought of defining my own function which can then be used as
the value of `indent-line-function' in nXML mode.  However, I don't know
how to define `<my custom indentation rules>', so that they apply only
to text children of elements.

Do you have any suggestions on that?

Best regards,
Raghu.

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08  4:33 ` N. Raghavendra
  2018-05-08  4:55   ` Yuri Khan
@ 2018-05-08  8:09   ` N. Raghavendra
  2018-05-08  8:19     ` Yuri Khan
  1 sibling, 1 reply; 9+ messages in thread
From: N. Raghavendra @ 2018-05-08  8:09 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-08T10:03:33+05:30, N. Raghavendra wrote:

> It looks like `nxml-compute-indent-from-previous-line' in nxml-mode.el
> is relevant, but I can't see how to modify or advise it.

I have made some progress, with this function.  I tried changing the
definition of `nxml-compute-indent-from-previous-line' as follows:

----------
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index e2b51bc..f2e185e 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -1377,10 +1377,17 @@ nxml-compute-indent-from-previous-line
                        (nxml-compute-indent-in-token bol))))
          (skip-chars-forward " \t\r\n"))
        (goto-char ref)
-	(+ (current-column)
-	   (* nxml-child-indent
-	      (+ (if (eq before-context 'start-tag) 1 0)
-		 (if (eq after-context 'end-tag) -1 0))))))))
+        (message "bc=%s ac=%s" before-context after-context)
+        (cond ((and (eq before-context 'mixed)
+                    (eq after-context 'markup))
+               (+ (current-column) nxml-child-indent))
+              ((and (eq before-context 'markup)
+                    (eq after-context 'markup))
+               (current-column))
+	      (t (+ (current-column)
+                   (* nxml-child-indent
+                      (+ (if (eq before-context 'start-tag) 1 0)
+                         (if (eq after-context 'end-tag) -1 0))))))))))

 (defun nxml-merge-indent-context-type (context)
   "Merge the indent context type CONTEXT with the token in `xmltok-type'.
----------

This almost gives me the indentation that I want, as in,

----------
<article>
  <section>
    <title>Kant lipsum</title>

    <para>Let us suppose that the noumena have nothing to do with
      necessity, since knowledge of the Categories is a posteriori.
      Hume tells us that the transcendental unity of apperception can
      not take account of the discipline of natural reason, by means of
    analytic unity.</para>
  </section>
</article>
----------

The only thing is that the last line in the para, the one starting with
"analytic", is not indented as I want it.  It should be indented to the
same column as the previous line, the one starting with "not".

I have put

(message "bc=%s ac=%s" before-context after-context)

to give me some idea of what is happening.  However, it does not produce
any message when I go to the troublesome last line of the para, and
press tab.

I'd appreciate if someone can help with this problem.  If it is better
off on emacs-devel, I'll move it there.

Thanks,
Raghu.

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08  8:09   ` N. Raghavendra
@ 2018-05-08  8:19     ` Yuri Khan
  2018-05-08 15:30       ` N. Raghavendra
  0 siblings, 1 reply; 9+ messages in thread
From: Yuri Khan @ 2018-05-08  8:19 UTC (permalink / raw)
  To: nyraghu27132, help-gnu-emacs

On Tue, May 8, 2018 at 3:09 PM N. Raghavendra <nyraghu27132@gmail.com>
wrote:

> I have made some progress, with this function.  I tried changing the
> definition of `nxml-compute-indent-from-previous-line' as follows:

> This almost gives me the indentation that I want, as in,

> ----------
>      <para>Let us suppose that the noumena have nothing to do with
>        necessity, since knowledge of the Categories is a posteriori.
>        Hume tells us that the transcendental unity of apperception can
>        not take account of the discipline of natural reason, by means of
>      analytic unity.</para>
> ----------

> The only thing is that the last line in the para, the one starting with
> "analytic", is not indented as I want it.  It should be indented to the
> same column as the previous line, the one starting with "not".

> I have put

> (message "bc=%s ac=%s" before-context after-context)

> to give me some idea of what is happening.  However, it does not produce
> any message when I go to the troublesome last line of the para, and
> press tab.

That probably means the indentation for that line is computed in
‘nxml-compute-indent-from-matching-start-tag’.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08  8:19     ` Yuri Khan
@ 2018-05-08 15:30       ` N. Raghavendra
  2018-05-09  3:22         ` N. Raghavendra
  0 siblings, 1 reply; 9+ messages in thread
From: N. Raghavendra @ 2018-05-08 15:30 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-08T08:19:45Z, Yuri Khan wrote:

> On Tue, May 8, 2018 at 3:09 PM N. Raghavendra <nyraghu27132@gmail.com>
> wrote:
>
> That probably means the indentation for that line is computed in
> ‘nxml-compute-indent-from-matching-start-tag’.

Thank you, that's absolutely correct, as I confirmed by putting a
`message' form at the end of that function.  I have now changed
nxml-mode.el as in the diff below.  With that, I get the required
indentation, as in

----------
<article>
  <section>
    <title>Kant lipsum</title>

    <para>Let us suppose that the noumena have nothing to do with
      necessity, since knowledge of the Categories is a posteriori.
      Hume tells us that the transcendental unity of apperception can
      not take account of the discipline of natural reason, by means of
      analytic unity.</para>
  </section>
</article>
----------

The change to `nxml-compute-indent-from-matching-start-tag' introduces a
local variable `only-end-tag' to distinguish between the line starting
with "analytic", and the last two lines.

Now, the next thing I see is that if, after this indentation, I do
`fill-paragraph', it goes back to the old indentation.  Anyway, I'll
deal with that later.  For now, I'll make do with these changes, which
at least give me the indentation I want.

Thanks very much for your help.

Best regards,

Raghu.

----------
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index e2b51bc..a2e92f4 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -1297,14 +1297,16 @@ nxml-compute-indent-from-matching-start-tag
 its line.  Otherwise return nil."
   (save-excursion
     (back-to-indentation)
-    (let ((bol (point)))
+    (let ((bol (point))
+          (only-end-tag nil))
       (let ((inhibit-field-text-motion t))
        (end-of-line))
       (skip-chars-backward " \t")
       (and (= (nxml-token-before) (point))
           (memq xmltok-type '(end-tag partial-end-tag))
           ;; start of line must not be inside a token
-	   (or (= xmltok-start bol)
+	   (or (and (= xmltok-start bol)
+                    (setq only-end-tag t))
               (save-excursion
                 (goto-char bol)
                 (nxml-token-after)
@@ -1322,7 +1324,9 @@ nxml-compute-indent-from-matching-start-tag
             (goto-char xmltok-start)
             (skip-chars-backward " \t")
             (bolp))
-	   (current-indentation)))))
+           (if only-end-tag
+	       (current-indentation)
+             (+ (current-indentation) nxml-child-indent))))))

 (defun nxml-compute-indent-from-previous-line ()
   "Compute the indent for a line using the indentation of a previous line."
@@ -1377,10 +1381,17 @@ nxml-compute-indent-from-previous-line
                        (nxml-compute-indent-in-token bol))))
          (skip-chars-forward " \t\r\n"))
        (goto-char ref)
-	(+ (current-column)
-	   (* nxml-child-indent
-	      (+ (if (eq before-context 'start-tag) 1 0)
-		 (if (eq after-context 'end-tag) -1 0))))))))
+        (message "bc=%s ac=%s" before-context after-context)
+        (cond ((and (eq before-context 'mixed)
+                    (eq after-context 'markup))
+               (+ (current-column) nxml-child-indent))
+              ((and (eq before-context 'markup)
+                    (eq after-context 'markup))
+               (current-column))
+	      (t (+ (current-column)
+                   (* nxml-child-indent
+                      (+ (if (eq before-context 'start-tag) 1 0)
+                         (if (eq after-context 'end-tag) -1 0))))))))))

 (defun nxml-merge-indent-context-type (context)
   "Merge the indent context type CONTEXT with the token in `xmltok-type'.
----------

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-08 15:30       ` N. Raghavendra
@ 2018-05-09  3:22         ` N. Raghavendra
  2018-05-12  4:36           ` N. Raghavendra
  0 siblings, 1 reply; 9+ messages in thread
From: N. Raghavendra @ 2018-05-09  3:22 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-08T21:00:14+05:30, N. Raghavendra wrote:

> Now, the next thing I see is that if, after this indentation, I do
> `fill-paragraph', it goes back to the old indentation.  Anyway, I'll
> deal with that later.  For now, I'll make do with these changes, which
> at least give me the indentation I want.

I've found a fix for this also.

I've seen references to difficulties with nXML mode indentation, so I am
enclosing the changes in case someone else is bugged by the problem.
Using the advice mechanism seems a kludge, but it will do for me at
present.

Thanks,
Raghu.

----------
;; Fix indentation, so that it conforms to the guidelines of the
;; FreeBSD Documentation Project.
;; https://www.freebsd.org/doc/en_US.ISO8859-1/books/fdp-primer/writing-style-guide.html#writing-style-indentation

(defun my-nxml-compute-indent-from-matching-start-tag ()
  "Compute the indent for an end tag line using its start tag.
This function is meant to be an overriding advice for
`nxml-compute-indent-from-matching-start-tag'.  Adds a
local variable ONLY-END-TAG to distinguish between end
tags that are alone on a line, from end tags that are
accompanied by text on a line."
  (save-excursion
    (back-to-indentation)
    (let ((bol (point))
          (only-end-tag nil))
      (let ((inhibit-field-text-motion t))
        (end-of-line))
      (skip-chars-backward " \t")
      (and (= (nxml-token-before) (point))
           (memq xmltok-type '(end-tag partial-end-tag))
           ;; start of line must not be inside a token
           (or (and (= xmltok-start bol)
                    (setq only-end-tag t))
               (save-excursion
                 (goto-char bol)
                 (nxml-token-after)
                 (= xmltok-start bol))
               (eq xmltok-type 'data))
           (condition-case nil
               (nxml-scan-element-backward
                (point)
                nil
                (- (point)
                   nxml-end-tag-indent-scan-distance))
             (nxml-scan-error nil))
           (< xmltok-start bol)
           (progn
             (goto-char xmltok-start)
             (skip-chars-backward " \t")
             (bolp))
           (if only-end-tag
               (current-indentation)
             (+ (current-indentation) nxml-child-indent))))))

(advice-add 'nxml-compute-indent-from-matching-start-tag :override
            #'my-nxml-compute-indent-from-matching-start-tag)

(defun my-nxml-compute-indent-from-previous-line ()
  "Compute the indent for a line using the previous line.
This function is meant to be an overriding advice for
`nxml-compute-indent-from-previous-line'.  Considers
extra cases depending on the context of the line."
  (save-excursion
    (end-of-line)
    (let ((eol (point))
          bol prev-bol ref
          before-context after-context)
      (back-to-indentation)
      (setq bol (point))
      (catch 'indent
        ;; Move backwards until the start of a non-blank line that is
        ;; not inside a token.
        (while (progn
                 (when (= (forward-line -1) -1)
                   (throw 'indent 0))
                 (back-to-indentation)
                 (if (looking-at "[ \t]*$")
                     t
                   (or prev-bol
                       (setq prev-bol (point)))
                   (nxml-token-after)
                   (not (or (= xmltok-start (point))
                            (eq xmltok-type 'data))))))
        (setq ref (point))
        ;; Now scan over tokens until the end of the line to be indented.
        ;; Determine the context before and after the beginning of the
        ;; line.
        (while (< (point) eol)
          (nxml-tokenize-forward)
          (cond ((<= bol xmltok-start)
                 (setq after-context
                       (nxml-merge-indent-context-type after-context)))
                ((and (<= (point) bol)
                      (not (and (eq xmltok-type 'partial-start-tag)
                                (= (point) bol))))
                 (setq before-context
                       (nxml-merge-indent-context-type before-context)))
                ((eq xmltok-type 'data)
                 (setq before-context
                       (nxml-merge-indent-context-type before-context))
                 (setq after-context
                       (nxml-merge-indent-context-type after-context)))
                ;; If in the middle of a token that looks inline,
                ;; then indent relative to the previous non-blank line
                ((eq (nxml-merge-indent-context-type before-context)
                     'mixed)
                 (goto-char prev-bol)
                 (throw 'indent (current-column)))
                (t
                 (throw 'indent
                        (nxml-compute-indent-in-token bol))))
          (skip-chars-forward " \t\r\n"))
        (goto-char ref)
        (cond ((and (eq before-context 'mixed)
                    (eq after-context 'markup))
               (+ (current-column) nxml-child-indent))
              ((and (eq before-context 'markup)
                    (eq after-context 'markup))
               (current-column))
              (t (+ (current-column)
                    (* nxml-child-indent
                       (+ (if (eq before-context 'start-tag) 1 0)
                          (if (eq after-context 'end-tag) -1 0))))))))))

(advice-add 'nxml-compute-indent-from-previous-line :override
            #'my-nxml-compute-indent-from-previous-line)

(defun my-nxml-do-fill-paragraph (arg)
  "Fill paragraph in `nxml-mode'.
This function is meant to be an overriding advice for
`nxml-do-fill-paragraph'.  Adds some space to `fill-prefix'."
  (let (fill-paragraph-function
        fill-prefix
        start end)
    (save-excursion
      (nxml-forward-paragraph)
      (setq end (point))
      (nxml-backward-paragraph)
      (skip-chars-forward " \t\r\n")
      (setq start (point))
      (beginning-of-line)
      (setq fill-prefix
            (concat
             (buffer-substring-no-properties (point) start)
             (make-string nxml-child-indent ?\s)))
      (when (and (not (nxml-get-inside (point)))
                 (looking-at "[ \t]*<!--"))
        (setq fill-prefix (concat fill-prefix "     ")))
      (fill-region-as-paragraph start end arg))
    (skip-line-prefix fill-prefix)
    fill-prefix))

(advice-add 'nxml-do-fill-paragraph :override
            #'my-nxml-do-fill-paragraph))
----------

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: nXML mode indentation
  2018-05-09  3:22         ` N. Raghavendra
@ 2018-05-12  4:36           ` N. Raghavendra
  0 siblings, 0 replies; 9+ messages in thread
From: N. Raghavendra @ 2018-05-12  4:36 UTC (permalink / raw)
  To: help-gnu-emacs

At 2018-05-09T08:52:36+05:30, N. Raghavendra wrote:

> I've found a fix for this also.
>
> I've seen references to difficulties with nXML mode indentation, so I am
> enclosing the changes in case someone else is bugged by the problem.
> Using the advice mechanism seems a kludge, but it will do for me at
> present.

Just for the record, my kludge doesn't work.  It works for simple
elements, but gives unwanted indentation for even slightly complex
elements.  So, I have to throw it away, and accept nXML mode's default
indentation, though it is different from that of sgml mode or psgml
mode.

Cheers,
Raghu.

--
N. Raghavendra <raghu@hri.res.in>, http://www.retrotexts.net/
Harish-Chandra Research Institute, http://www.hri.res.in/



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-05-12  4:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-05 13:38 nXML mode indentation N. Raghavendra
2018-05-08  4:33 ` N. Raghavendra
2018-05-08  4:55   ` Yuri Khan
2018-05-08  5:16     ` N. Raghavendra
2018-05-08  8:09   ` N. Raghavendra
2018-05-08  8:19     ` Yuri Khan
2018-05-08 15:30       ` N. Raghavendra
2018-05-09  3:22         ` N. Raghavendra
2018-05-12  4:36           ` N. Raghavendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).