SHINMERA.s_LASS/writer.lisp

69 lines
2.8 KiB
Common Lisp
Raw Normal View History

2014-09-03 18:48:37 +02:00
#|
This file is a part of LASS
2014-10-09 21:44:52 +02:00
(c) 2014 Shirakumo http://tymoon.eu (shinmera@tymoon.eu)
2014-09-03 18:48:37 +02:00
Author: Nicolas Hafner <shinmera@tymoon.eu>
|#
(in-package #:org.tymoonnext.lass)
(defvar *pretty* T
"Directs whether to pretty-print using whitespace or not.")
(defvar *indent-level* 0
"Directs the current amount of spaces used to indent.")
2014-09-03 18:48:37 +02:00
;; SHEET ::= (BLOCK*)
;; BLOCK ::= (:BLOCK SELECTOR PROPERTY*)
;; SELECTOR ::= (string*)
;; PROPERTY ::= (:PROPERTY string string)
2014-09-03 18:48:37 +02:00
2014-09-03 20:18:34 +02:00
(defun indent ()
2014-09-05 11:30:19 +02:00
"Returns a string of the appropriate number of spaces depending on *PRETTY* and *INDENT-LEVEL*"
2014-09-03 20:18:34 +02:00
(make-string (if *pretty* *indent-level* 0) :initial-element #\Space))
(defgeneric write-sheet-object (type object stream)
2014-09-05 11:30:19 +02:00
(:documentation "Writes the OBJECT of type TYPE to STREAM.
By default the following TYPEs are handled:
:BLOCK (SELECTOR-LIST OBJECTS*)
Prints the SELECTOR-LIST separated by commas, followed by an opening brace
and the printed list of OBJECTS using WRITE-SHEET-PART. Finally the body is
closed off with a closing brace. Newlines and spaces may be inserted where
necessary if *PRETTY* is non-NIL.
:PROPERTY (KEY VALUE)
Prints the KEY. If VALUE is non-NIL, a colon is printed followed by the
VALUE. Finally a semicolon is printed. Spaces may be inserted where necessary
if *PRETTY* is non-NIL.")
2014-09-03 20:18:34 +02:00
(:method ((type (eql :block)) block stream)
(when (and block (cdr block))
(let ((true-format (format NIL "~a~~{~~a~~^,~@[~%~:*~a~* ~]~~}{~:*~@[~*~%~]~~{~~/lass::write-sheet-part/~~^~:*~@[~*~%~]~~}~:*~@[~*~%~]~:*~:*~a~*}"
2014-09-03 20:18:34 +02:00
(indent) *pretty*))
(*indent-level* (+ *indent-level* 4)))
(format stream true-format
(car block) (cdr block)))))
2014-09-09 17:51:20 +02:00
(:method ((type (eql :property)) attribute stream)
2014-09-03 20:18:34 +02:00
(when attribute
(format stream (format NIL "~a~~a~~@[:~@[~* ~]~~a~~];" (indent) *pretty*)
2014-09-09 17:51:20 +02:00
(first attribute) (second attribute))))
(:method ((type (eql :text)) block stream)
(when block
(format stream "~{~a~}~@[~*~%~]" block *pretty*))))
2014-09-03 18:48:37 +02:00
2014-09-03 20:18:34 +02:00
(defun write-sheet-part (stream block cp ap)
2014-09-05 11:30:19 +02:00
"Wrapper around WRITE-SHEET-OBJECT so that we can call it from FORMAT.
Calls WRITE-SHEET-OBJECT with (CAR BLOCK) (CDR BLOCK) STREAM."
2014-09-03 18:48:37 +02:00
(declare (ignore cp ap))
2014-09-03 20:18:34 +02:00
(write-sheet-object (car block) (cdr block) stream))
2014-09-03 18:48:37 +02:00
(defun write-sheet (sheet &key (stream NIL) (pretty *pretty*))
2014-09-05 11:30:19 +02:00
"Writes the compiled SHEET object to STREAM.
If PRETTY is non-NIL, spaces and newlines are inserted as appropriate
in order to create a human-readable stylesheet. Otherwise whitespace is
only used where necessary, producing a minified version.
STREAM can be a STREAM, T for *STANDARD-OUTPUT*, or NIL for a STRING."
2014-09-03 18:48:37 +02:00
(let ((*pretty* pretty))
2014-09-03 20:18:34 +02:00
(format stream (format NIL "~~{~~/lass::write-sheet-part/~~^~@[~*~%~%~]~~}" pretty) sheet)))