<commit_before>(in-package :common-lisp-user)

(defpackage :dsgner
  (:use #:cl)
  (:export #:empty-string
	   #:deftag
	   #:deftags))

(in-package :dsgner)

(defun empty-string ()
  (make-array '(0) 
              :element-type 'base-char
              :fill-pointer 0
              :adjustable t))

(defmacro nif (test then &optional else)
  `(if (not ,test)
       ,then
       ,else))

(defun format-tag (stream tag attributes)
  (let ((output (format stream "<~A" tag)))
    (when attributes
      (do ((i 0 (+ i 2))
           (att attributes (cddr att))
           (len (length attributes)))
          ((>= i len))
        (concatenate 'string 
                     output
                     (format stream
                             " ~A=\"~A\""
                             (string-downcase (string (car att)))
                             (cadr att)))))
    output))
      
(defmacro with-use-tag ((tag) (&rest attributes) &body body)
  (let ((strsym (gensym))
	(attsym (gensym))
	(tagsym (gensym))
	(tag-name (string-downcase (string tag))))
    `(let (,@(nif (null attributes)
		  (list `(,attsym ',attributes)))
	   (,strsym (empty-string)))

       (with-output-to-string (,tagsym ,strsym)
         ;;handle attributes
         ,(nif (null attributes)
	       `(format-tag ,tagsym ,tag-name ,attsym)
	       `(format-tag ,tagsym ,tag-name nil))
	 
	 ;;handle BODY part
	 ,@(cond ((null body)
		  (list `(format ,tagsym " />")))

		 (t 
		  (append (list `(format ,tagsym ">"))
			  (mapcar #'(lambda (f) 
				      `(format ,tagsym "~A" ,f))
				  body)
			  (list `(format ,tagsym "</~A>" ,tag-name))))))
       ,strsym)))

(defmacro deftag (tag)
  `(defmacro ,tag ((&rest attribs) &body body)
     `(with-use-tag (,',tag)
	,attribs
        ,@body)))

(defmacro deftags (&rest tags)
  `(progn
     ,@(mapcar #'(lambda(tag)
                   `(deftag ,tag))
               tags)))<commit_msg>bugfix: attribs can be eval..ed<commit_after>(in-package :common-lisp-user)

(defpackage :dsgner
  (:use #:cl)
  (:export #:empty-string
	   #:deftag
	   #:deftags))

(in-package :dsgner)

(defun empty-string ()
  (make-array '(0) 
              :element-type 'base-char
              :fill-pointer 0
              :adjustable t))

(defmacro nif (test then &optional else)
  `(if (not ,test)
       ,then
       ,else))

(defmacro format-tag (stream tag &rest attributes)
  (let ((alen (length attributes))
	(fs "")
	(acount 0))
    (do ((i 0 (+ i 2)))
	((>= i alen))
      (setf fs (concatenate 'string 
			    fs 
			    (format nil "~A" " ~A=\"~A\""))))
    `(format ,stream ,(format nil "<~A~A" "~A" fs)
	     ,tag
	     ,@(mapcar #'(lambda(a)
			   (incf acount)
			   (if (zerop (mod acount 2))
			       a
			       (string-downcase (string a))))
		       attributes))))


;;this is used in order not to use
;;with-output-to-string macro more than once 
(defun dscanner ()
  (let ((depth 0))    
    (values 
     ;;returns depth
     (lambda ()
       depth)
     
     ;;incf depth
     (lambda()
       (incf depth))
     
     ;;decf depth
     (lambda()
       (decf depth)))))


(defmacro with-use-tag ((tag) (&rest attributes) &body body)
  (let ((strsym (gensym))
	(tagsym (gensym))
	(tag-name (string-downcase (string tag))))
    (let ((base-list 
	    (append 
	       ;;handle attributes
	       (nif (null attributes)
		    (list `(format-tag ,tagsym ,tag-name ,@attributes))
		    (list `(format-tag ,tagsym ,tag-name)))
	       
	       ;;handle BODY part
	       (cond ((null body)
		      (list `(format ,tagsym " />")))
		     
		     (t 
		      (append (list `(format ,tagsym ">"))
			      (mapcar #'(lambda (f) 
					  `(format ,tagsym "~A" ,f))
				      body)
			      (list `(format ,tagsym "</~A>" ,tag-name))))))))
      
      `(let ((,strsym (empty-string)))
	 (with-output-to-string (,tagsym ,strsym)
	   ,@base-list)
	 ,strsym))))

(defmacro deftag (tag)
  `(defmacro ,tag ((&rest attribs) &body body)
     `(with-use-tag (,',tag)
	,attribs
        ,@body)))

(defmacro deftags (&rest tags)
  `(progn
     ,@(mapcar #'(lambda(tag)
                   `(deftag ,tag))
               tags)))
{'fraction_non_alphanumeric': 0.17693981145757795, 'fraction_numerical': 0.0026589315929417454, 'mean_word_length': 2.0248538011695905, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3246903', 'n_tokens_mistral': 1586, 'n_tokens_neox': 1431, 'n_words': 378}