Re: RE: (dsssl) simple loop question

Subject: Re: RE: (dsssl) simple loop question
From: Paul Tyson <paul@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 12 Apr 2003 12:18:02 -0500
When Miroslaw first posted his question, I thought he wanted to put 
chunks of #PCDATA that occur inside of a mixed-content element into a 
<mi> element in the output.  Subsequent posts seemed to show that he 
wanted to put <mi> tags around each individual character.  That's what 
Miroslaw's latest code does.

It is a little more difficult to wrap a chunk of data in an element if 
the data occurs in a mixed-content element.  The general problem is to 
add hierarchical structure to any linear sequence of nodes.  The DSSSL 
processing model makes it easy to recursively process through an 
existing hierarchical structure, but it is slightly more difficult to 
add hierarchical structure to a flat sequence.

Here is one way to eliminate mixed-content data.

Input document:
<!doctype testmi [
<!element testmi - o (mix+)>
<!element mix - - (#PCDATA | foo)* >
<!element foo - - (#PCDATA)>
]>
<testmi>
  <mix>abc<foo>the foo element</foo> more mix</mix>
</testmi>

DSSSL fragment:
(define wrap-chunk-with-mi 
  (lambda (#!optional (nl (children (current-node))))
    (if (node-list-empty? nl)
	(empty-sosofo)
	(let* ((is-first-child-data?
	       (equal? 'data-char 
		       (node-property 'class-name (node-list-first nl))))
	       (to-do (if is-first-child-data?
			  (node-list-after-data nl)
			  (node-list-rest nl))))
	  (sosofo-append
	   (if is-first-child-data?
	       (make element gi: "mi"
		     (process-node-list (get-leading-data-nodes nl)))
	       (process-node-list (node-list-first nl)))
	   (wrap-chunk-with-mi to-do))))))

(define get-leading-data-nodes
  (lambda (nl)
    (let loop ((to-do nl)
	       (data (empty-node-list)))
      (if (or (node-list-empty? to-do)
	      (not (equal? 'data-char 
			   (node-property 'class-name 
					  (node-list-first to-do)))))
	  data
	  (loop (node-list-rest to-do)
		(node-list data (node-list-first to-do)))))))

(define node-list-after-data
  (lambda (nl)
    (if (node-list-empty? nl)
	nl
	(if (equal? 'data-char 
		    (node-property 'class-name (node-list-first nl)))
	    (node-list-after-data (node-list-rest nl))
	    nl))))
  
(element mix
  (make element gi: "new-mix"
	(wrap-chunk-with-mi)))

(element foo
  (make element gi: "new-foo"
	(process-children-trim)))

(root
  (make element gi: "new-doc"
	(process-children)))

Output document:
<new-doc>
<new-mix><mi>abc</mi>
<new-foo>the foo element</new-foo>
<mi> more mix</mi>
</new-mix>
</new-doc>


I didn't browse the DSSSL sites for any general procedures to do this 
sort of processing, but it is a common enough problem that there 
should be instructions for it somewhere.

4/11/03 3:06:04 AM, Miroslaw Prywata <Miroslaw.Prywata@xxxxxxxxxx> 
wrote:

>Maybe I shouldn't answer my own post, but I found a mistake :-))
>
>> -----Original Message-----
>> From: Miroslaw Prywata [mailto:Miroslaw.Prywata@xxxxxxxxxx]
>
>> (define wrap-with-mi (lambda (#!optional (nl (children 
>> (current-node))))
>>     (let loop ((n nl) (result empty-sosofo))
>
>Here I changed the second argument to (result (literal ""))
>openjade was complaining empty-sosofo is not sosofo :)
>
>>         (if (node-list-empty? n)
>>             result
>>         (let* ((cn (node-list-first n))   (c (node-property 
>> 'class-name
>> cn)))
>>             (loop
>>                 (node-list-rest n)
>>                 (sosofo-append
>
>I have to append current value to result, so there is one missing 
line:
>
>result
>
>>                     (if (equal? 'data-char c)
>>                         (make element gi: "mi"
>>                             (literal (string (node-property 
>> 'char cn))))
>>                         (process-node-list cn)
>>                     ))
>>             ); loop
>>             );let
>>        );if
>> );let
>> ))
>
>The whole function looks lite this:
>
>(define wrap-with-mi (lambda (#!optional (nl (children (current-
node))))
>    (let loop ((n nl) (result (literal "")))
>        (if (node-list-empty? n)
>            result
>        (let* ((cn (node-list-first n))   (c (node-property 'class-
name
>cn)))
>            (loop
>                (node-list-rest n)
>                (sosofo-append
>                    result
>                    (if (equal? 'data-char c)
>                        (make element gi: "mi"
>                            (literal (string (node-property 'char 
cn))))
>                    (process-node-list cn)
>                    ))
>            ); loop
>            );let
>       );if
>);let
>))
>
>Mirek
>
> DSSSList info and archive:  
http://www.mulberrytech.com/dsssl/dssslist
>

Paul Tyson, Principal Consultant          Precision Documents
paul@xxxxxxxxxxxxxxxxxxxxxx     http://precisiondocuments.com
      "The art and science of document engineering."




 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist

Current Thread