Initialize chat block processor

This commit is contained in:
Gabriel Arazas 2023-04-03 23:35:18 +08:00
parent 86a1afa512
commit 1fc5e7c01a
3 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1,105 @@
= Chat block processor
:toc:
A link:https://docs.asciidoctor.org/asciidoctor/latest/extensions/block-processor/[block processor] that adds a a dialog box style to the block.
Exclusive to the HTML backend.
== Synopsis
....
[chat, $AVATARNAME, $AVATARSTATE, $ATTRS...]
====
$CONTENT
====
....
The avatar name is the name of the folder to be retrieved from the `avatarsdir` attribute.
The directory enforces a certain structure which can be seen in <<extra-notes>>.
Both the avatar name and the state are to be converted to snake case (e.g., `El Pablo` to `el_pablo`) for the image path.
== Attributes
* `avatarsdir` is the folder containing the avatars' stickers.
This is explained in detail from the <<extra-notes>> section.
* `avatarstype` is similar to `icontype` attribute except this is used for the avatar stickers.
The default value is `webp`.
* `state` is the sticker to be retrieved from the avatars directory.
It has a default value of `default`.
You could also use this attribute instead of the `$AVATARSTATE` positional argument for whatever reason.
* `name` is the canonical name of the avatar.
This is used for titles and alts in the internal image block.
By default, this is the same as the given avatar.
[#extra-notes]
== Extra notes
This component has some prerequisites for this to fully work specifically with `avatarsdir` attribute that contains a list of avatars and their stickers.
By default, this value is at the `avatars` subdirectory of the `iconsdir` attribute.
It is recommended to set this value yourself.
+
--
This enforces a certain structure where the root directory contains a list of folders representing the avatar with each of the folder containing stickers which represents their state.
For example, here's what `avatarsdir` could contain following the expected structure.
[source]
----
./static/icons/avatars/
├── ezran/
│ ├── crisis.webp
│ ├── default.webp
│ ├── sad.webp
│ └── shocked.webp
└── foodogsquared/
├── crisis.webp
├── default.webp
├── sad.webp
└── shocked.webp
----
--
== Example usage
Let's assume `avatarsdir` is set to the `static/icons/avatars` with the following file structure.
[source]
----
./static/icons/avatars/
├── ezran/
│ ├── crisis.webp
│ ├── default.webp
│ ├── sad.webp
│ └── shocked.webp
├── el-pablo/
│ ├── crisis.webp
│ ├── default.webp
│ ├── ghastly.webp
│ ├── melodramatic.webp
│ ├── sad.webp
│ └── shocked.webp
└── foodogsquared/
├── crisis.webp
├── default.webp
├── sad.webp
└── shocked.webp
----
- The following block should get the default image for `foodogsquared` which is in `./static/icons/avatars/foodogsquared/default.webp`.
+
....
[chat, foodogsquared]
====
Hello there!
====
....
- The following block should contain El Pablo's melodramatic dialog state.
Take note

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
class ChatBlock < Asciidoctor::Extensions::BlockProcessor
use_dsl
named :chat
on_context :example
name_positional_attributes 'avatar', 'state'
default_attributes 'state' => 'default', 'avatarstype' => 'webp'
def process(parent, reader, attrs)
block = create_block parent, :pass, nil, attrs, content_model: :compound
block.add_role('dialogblock')
# You can think of this section as a pipeline constructing the HTML
# component for this block. Specifically, we're building one component that
# contains two output: the dialog image of our avatar and its content.
attrs['name'] ||= attrs['avatar']
block << (create_html_fragment block, %(
<div class="dialogblock dialogblock__box dialogblock__avatar--#{attrs['avatar']} #{attrs['role']}" title="#{attrs['avatar']}">
<div class="dialogblock dialogblock__avatar">
))
attrs['avatarsdir'] ||= File.expand_path('./avatars', attrs['iconsdir'])
avatar_sticker = "#{attrs['avatar'].to_snake}/#{attrs['state'].to_snake}.#{attrs['avatarstype']}"
avatar_img_attrs = {
'target' => parent.image_uri(avatar_sticker, 'avatarsdir'),
'alt' => attrs['name']
}
avatar_imgblock = create_image_block block, avatar_img_attrs
block << avatar_imgblock
block << (create_html_fragment block, %(
</div>
<div class="dialogblock dialogblock__text">
))
parse_content block, reader
block << (create_html_fragment block, %(
</div>
</div>
))
block
end
private
def create_html_fragment(parent, html, attributes = nil)
create_block parent, :pass, html, attributes
end
end

View File

@ -12,9 +12,11 @@ require_relative 'github-link-inline-macro/extension'
require_relative 'github-raw-content-include-processor/extension'
require_relative 'gitlab-link-inline-macro/extension'
require_relative 'gitlab-raw-content-include-processor/extension'
require_relative 'chat-block-processor/extension'
Asciidoctor::Extensions.register do
inline_macro ManInlineMacro
block ChatBlock if @document.basebackend? 'html'
inline_macro SWHInlineMacro
include_processor SWHIDIncludeProcessor