From f8a6d6d40f2363ffb61c930e6e3367ca13b318a5 Mon Sep 17 00:00:00 2001 From: Kinneyzhang Date: Wed, 5 Aug 2026 06:59:23 +0800 Subject: [PATCH] feat(playground): add Ebox layout examples Provide a standalone public-API-only Ebox playground demonstrating Grid layout and buffer lifecycle with tests and bilingual README documentation. --- .gitignore | 2 ++ Makefile | 28 +++++++++++++++++ README.md | 10 ++++++ README.zh-CN.md | 10 ++++++ ebox-playground.el | 57 ++++++++++++++++++++++++++++++++++ tests/ebox-playground-tests.el | 26 ++++++++++++++++ 6 files changed, 133 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 README.zh-CN.md create mode 100644 ebox-playground.el create mode 100644 tests/ebox-playground-tests.el diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3daa17c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.elc +tests/*.elc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a424bbc --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +EMACS ?= emacs +LOAD_PATH = -L . -L ../emacs-box + +.PHONY: all compile test check checkdoc load clean + +all: check + +compile: + rm -f *.elc tests/*.elc + $(EMACS) -Q --batch $(LOAD_PATH) --eval '(setq load-prefer-newer t)' \ + --eval '(load-file "ebox-playground.el")' \ + --eval '(byte-compile-file "ebox-playground.el")' + +test: compile + $(EMACS) -Q --batch $(LOAD_PATH) --eval '(setq load-prefer-newer t)' \ + -l tests/ebox-playground-tests.el -f ert-run-tests-batch-and-exit + +load: compile + $(EMACS) -Q --batch $(LOAD_PATH) --eval '(require (quote ebox-playground))' \ + --eval '(princ "ebox-playground load OK\n")' + +checkdoc: + $(EMACS) -Q --batch --eval '(progn (require (quote checkdoc)) (dolist (file (directory-files "." t)) (when (string-suffix-p ".el" file) (checkdoc-file file))))' + +check: checkdoc compile test + +clean: + rm -f *.elc tests/*.elc diff --git a/README.md b/README.md new file mode 100644 index 0000000..03a57f9 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# ebox-playground + +`ebox-playground` is the independent developer example package for Ebox. It uses only public Ebox constructors and demonstrates fixed, fractional, two-dimensional, and placed layout. It is separate from `etaf-playground`, which demonstrates the higher-level Component and Runtime framework. + +```elisp +(require 'ebox-playground) +(ebox-playground-open) +``` + +Run `make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs` from this directory. diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..60505ff --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,10 @@ +# ebox-playground + +`ebox-playground` 是 Ebox 的独立开发示例包,只使用 Ebox 公共构造函数,展示固定轨道、分数轨道、二维 Grid 和显式放置。它与展示高层 Component/Runtime 框架的 `etaf-playground` 分开。 + +```elisp +(require 'ebox-playground) +(ebox-playground-open) +``` + +在该目录运行 `make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs`。 diff --git a/ebox-playground.el b/ebox-playground.el new file mode 100644 index 0000000..a678158 --- /dev/null +++ b/ebox-playground.el @@ -0,0 +1,57 @@ +;;; ebox-playground.el --- Public Ebox layout examples -*- lexical-binding: t; -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later +;; Author: Ebox contributors +;; Version: 0.1.0 +;; Package-Requires: ((emacs "29.1") (ebox "1.0.1")) +;; URL: https://github.com/ginqi7/ebox-playground + +;;; Commentary: + +;; This package is intentionally small and public-only. It demonstrates the +;; Ebox contract without reaching into ebox-- internals. ETAF's application +;; examples live in the sibling `etaf-playground' package. + +;;; Code: + +(require 'ebox) + +(defconst ebox-playground-buffer-name "*Ebox Playground*" + "Default buffer name used by `ebox-playground-open'.") + +;;;###autoload +(defun ebox-playground-view () + "Return a public Ebox example layout node without buffer side effects." + (ebox-grid + :width '(640) + :grid-template-columns '((200) 1fr) + :grid-template-rows '(1 1 1) + :gap '(1 (12)) + :padding '(1 2) + :border '((1) solid "#687386") + (ebox-create :content "Ebox Playground" :face 'bold) + (ebox-create :content "A pixel-precise two-dimensional layout") + (ebox-create :content "Row / column / flex / grid share the public node contract") + (ebox-create :content "Fixed and fractional tracks") + (ebox-create :content "Placement" :grid-column 1 :grid-row 3) + (ebox-create :content "No private calls" :grid-column 2 :grid-row 3))) + +;;;###autoload +(defun ebox-playground-open (&optional buffer-name) + "Render the public Ebox example into BUFFER-NAME and return its buffer." + (interactive) + (ebox-render-to-buffer (or buffer-name ebox-playground-buffer-name) + (ebox-playground-view))) + +;;;###autoload +(defun ebox-playground-close (&optional buffer-name) + "Kill the playground BUFFER-NAME and return its former buffer." + (interactive) + (let ((buffer (get-buffer (or buffer-name ebox-playground-buffer-name)))) + (when buffer + (kill-buffer buffer)) + buffer)) + +(provide 'ebox-playground) + +;;; ebox-playground.el ends here diff --git a/tests/ebox-playground-tests.el b/tests/ebox-playground-tests.el new file mode 100644 index 0000000..484185b --- /dev/null +++ b/tests/ebox-playground-tests.el @@ -0,0 +1,26 @@ +;;; ebox-playground-tests.el --- Public Ebox example tests -*- lexical-binding: t; -*- + +(require 'ert) +(require 'ebox-playground) + +(ert-deftest ebox-playground-uses-only-public-layout-apis () + "The example should build and render through the public Ebox entry point." + (let ((node (ebox-playground-view))) + (should (eq (plist-get node :ebox-type) 'grid)) + (should (string-match-p "Ebox Playground" + (substring-no-properties (ebox-render node)))))) + +(ert-deftest ebox-playground-opens-and-closes-buffer () + "The public open and close commands should own their buffer lifecycle." + (let ((name " *ebox-playground-test*")) + (unwind-protect + (progn + (ebox-playground-open name) + (should (buffer-live-p (get-buffer name))) + (with-current-buffer name + (should (string-match-p "Ebox Playground" (buffer-string))))) + (ebox-playground-close name)))) + +(provide 'ebox-playground-tests) + +;;; ebox-playground-tests.el ends here