Infobox
The highligters and wrappers were parsed in the wacko_preprocess()
of the WackoFormatter.
<?php /* * WackoFormatter * * Formats text with wacko-formatting. * Links and actions aren't processed. Its processed by PostWacko formatter */ // . . . $result = $wacko->_format($code, 'highlight/' . $formatter, $params); // add wrapper if (isset($params['wrapper']) && ($params['wrapper'] != 'none')) { $wrapper = 'wrapper_' . $params['wrapper']; $params['wrapper'] = ''; // no recursion $result = $wacko->_format(trim($result), 'highlight/' . $wrapper, $params); }
- extend the wrappers
box
andshade
- add formatter for
callout
- arguments for formatter and wrapper
-
type
-
title
-
icon
-
col
-
- add prefix
wrapper_
for wrapper arguments
Wrappers were parsed after the highlighter...
Formatter
-
%%(info type="warning" title="Warning") Formatter info.%%
Wrapper
-
%%(wacko wrapper="shade" wrapper_type="warning" wrapper_title="Warning") Formatter wacko with shade wrapper.%%
1. Issues
- nesting
- Nested formatters / wrappers are currently not feasible, that means you cant wrap a page or a section of o page in a wrapper, if it already contains a formatter (see exception below)
- As character markup for text formatters, you can use percent signs
%%, %%
or grave accents``, ``
. Both characters are equal. Grave accents can be useful if the text already contains percent signs, which may be mistakenly considered markup.
Beyond that this allows you to wrap a formatter in a formatter, e.g. wrapping a CSS highlighter in a details formatter.
- CSS for print and wordprocessor
-
Resetbody_r
after changing CSS class for wrapper to.wrapper
and.wrapper-content
-
SVG: set only viewbox- all SVG background images require a change, so we can set the icon size in the CSS file, e.g.
<span>text</span>
and.success span::before{}
. - added CSS class
msg
:<div class="msg note">
- all SVG background images require a change, so we can set the icon size in the CSS file, e.g.
-
CSS: definemin-height
for both containers - use
type
to assign style only to paragraph<p class="type-warning">
- Unicode icon versus SVG icon
- Paragrafica & Formatters:
<ignore>
terminator versus auto-paragraphs - it is too colorful, reduce and simplify color usage
- make
icon
optional in container and wrapper title
2. Formatter
Formatter Examples
Test here...2.1. Callout
%%(info type="warning" title="Warning") Formatter info.%%
Warning
Formatter info.formatter/highlight/info.php
<?php /* %%(info [type="default | error | example | important | note | question | quote | success | warning"] [title="Title"] [icon=0|1] [style="no use"] ) content %% */ $types = ['default', 'error', 'example', 'important', 'note', 'question', 'quote', 'success', 'warning']; // defaults $options['type'] ??= 'default'; $options['title'] ??= ''; $options['icon'] ??= 1; $options['style'] ??= false; $options['tpl'] = true; if (in_array($options['type'], $types)) { // info type-* in wacko.css $tpl->type = ' type-' . $options['type']; } if ($options['icon']) { $tpl->icon = true; $tpl->eicon = true; } $tpl->style = 'info'; $tpl->t_title = $options['title'] ?? null; $tpl->include = include Ut::join_path(FORMATTER_DIR, 'wiki.php');
formatter/highlight/template/info.tpl
[ === main === ] <ignore> <div class="[ ' style ' ][ ' type ' ]"> [= icon _ = [ ' nonstatic ' ] <div class="info-content"> =] [= t _ = <p class="info-title">[ ' title | e ' ]</p> =] [ ' include // <-- no indention for embeded pre ' ] [= eicon _ = [ ' nonstatic ' ] </div> =] </div> </ignore>
2.2. Pre-configured formatter
formatter/highlight/customized.php
<?php // set wrapper options $options['wrapper'] = 'box'; $options['wrapper_align'] = $options['align']; $options['wrapper_width'] = $options['width']; // add / include highlighter / formatter ... echo Ut::html($text);
3. Color scheme
type | background | color | border |
---|---|---|---|
default | rgb(147, 154, 69,.1) | #939A45 | |
important | rgba(255,23,68,.1) | #ff1744 | |
note | rgba(68,138,255,.1) | #448aff | |
warning | rgba(255,145,0,.1) | #ff9100 | |
success | rgba(0,200,83,.1) | #00c853 | |
question | rgba(100,221,23,.1) | #64dd17 | |
error | rgba(255,82,82,.1) | #ff5252 | |
example | rgba(101,31,255,.1) | #651fff | |
quote | hsla(0,0%,62%,.1) | #9e9e9e | |
summary | rgba(224, 203, 82,.1) | #e0cb52 |
4. Types
- note, tip, hint, nota bene *
- abstract, summary
- error, failure, fail
- important, attention
- success
- question, help, faq
- warning, caution, attention, danger
- issue, bug
- example, snippet
- quote, cite
* info
is used as a meta term for the formatter.
5. Layout
- info
<ignore> <div class="info type-note"> <div class="info-content"> <p class="info-title">Info</p> </div> </div> </ignore>
- <div>
- <aside>
- <p>
<ignore>
is terminator tag for Paragrafica, gets parsed away in the process
5.1. Icon
5.1.1. background:
span.icon{ /* background-size: 16px 16px;*/ /* ! required for span width -> inline element */ display: inline-block; height: 16px; width: 0; vertical-align: text-bottom; /* middle */ } a.external-link .icon { background: rgba(0, 0, 0, 0) url('./../icon/web.svg') no-repeat scroll left center; padding-left: 17px; }
5.1.2. before::
span.icon { position: relative; padding: 0 1rem 0 0; vertical-align: middle; /* text-bottom */ } .icon::before{ position: absolute; height: 1rem; width: 1rem; } a.external-link .icon::before { content: url('./../icon/web.svg') " "; }
6. CSS
color
background
border
icon
# | type | hl | class | icon | svg | syntax |
---|---|---|---|---|---|---|
1 | default | βΉ | ||||
2 | error | β | ||||
3 | example | π‘ | ||||
4 | ||||||
5 | important | ! | ||||
6 | note | β | ||||
7 | question | ? | ||||
8 | quote | β | ||||
9 | success | β | ||||
10 | warning | β | ||||
custom | ||||||
6.1. Icons
6.1.1. Unicode
.callout.type-fail > .callout-title::before { color: #ff5252; content: "β" }
πβ βοΈββ π«ββπ
πβ βββ
ππ₯ππ§
ββπππ‘ββποΈβ°πΎ
βΉπππ₯β‘βοΈββββ
ββΒΆ π·βοΈπ§
6.1.2. SVG
.callout.type-fail > .callout-title::before { content: url('./../icon/report-bug.svg') " "; height: 1rem; width: 1rem; }
6.2. wacko.css
/* Callouts: SYNTAX % %(callout type="warning" title="Warning")text% % */ /* 1. default */ .info, .wrapper { /* box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2); */ position: relative; margin: 1em 0; padding: .4rem .6rem; border: .05rem solid rgb(147, 154, 69,.1); border-left: .2rem solid #939a45; border-radius: .1rem; min-height: 5em; overflow: auto; } .wrapper-title { margin: -.4rem -.6rem .4rem -.6rem; padding: .4rem .6rem .4rem 2rem; /* border-bottom: .05rem solid rgba(68,138,255,.1); background-color: rgba(68,138,255,.1); */ font-weight: 700; } .info.type-default, .wrapper.type-default, .wrapper-title { border-bottom: .05rem solid rgb(147, 154, 69,.1); background-color: rgb(147, 154, 69,.1); } .wrapper > .wrapper-title::before { position: absolute; left: .6rem; color: #939a45; font-size: 1rem; content: "i"; height: 1rem; width: 1rem; font-family: "Times New Roman", Times, serif; } /* 2. note */ .info.type-note { border-color: rgba(68,138,255,.1); border-left-color: #448aff; } .info.type-note, .wrapper.type-note, .wrapper.type-note > .wrapper-title { background-color: rgba(68,138,255,.1); } .wrapper.type-note > .wrapper-title { border-bottom-color: rgba(68,138,255,.1); } .info.type-note > .info-content::before, .wrapper.type-note > .wrapper-title::before { color: #448aff; content: "β"; } /* 3. warning */ .info.type-warning { border-color: rgba(255,145,0,.1); border-left-color: #ff9100; } .info.type-warning, .wrapper.type-warning, .wrapper.type-warning > .wrapper-title { background-color: rgba(255,145,0,.1); } .wrapper.type-warning > .wrapper-title { border-bottom-color: rgba(255,145,0,.1); } .info.type-warning > .info-content::before, .wrapper.type-warning > .wrapper-title::before { color: #ff9100; content: "β "; /* content: url('./../icon/warning.svg') " "; */ } /* 4. success */ .info.type-success { border-color: rgba(100,221,23,.1); border-left-color: #64dd17; } .info.type-success, .wrapper.type-success, .wrapper.type-success > .wrapper-title { background-color: rgba(100,221,23,.1); } .wrapper.type-success > .wrapper-title { border-bottom-color: rgba(100,221,23,.1); } .info.type-success > .info-content::before, .wrapper.type-success > .wrapper-title::before { color: #64dd17; content: "β"; } /* 5. question */ .info.type-question { border-color: rgba(224, 203, 82,.1); border-left-color: #e0cb52; } .info.type-question, .wrapper.type-question, .wrapper.type-question > .wrapper-title { background-color: rgba(224, 203, 82,.1); } .wrapper.type-question > .wrapper-title { border-bottom-color: rgba(224, 203, 82,.1); } .info.type-question > .info-content::before, .wrapper.type-question > .wrapper-title::before { color: #e0cb52; content: "?"; } /* 6. error */ .info.type-error { border-color: rgba(255,82,82,.1); border-left-color: #ff5252; } .info.type-error, .wrapper.type-error, .wrapper.type-error > .wrapper-title { background-color: rgba(255,82,82,.1); } .wrapper.type-error > .wrapper-title { border-bottom-color: rgba(255,82,82,.1); } .info.type-error > .info-content::before, .wrapper.type-error > .wrapper-title::before { color: #ff5252; content: "β"; /* content: url('./../icon/cross.svg') " "; height: 1rem; width: 1rem; */ } /* 7. example */ .info.type-example { border-left-color: #651fff; } .info.type-example, .wrapper.type-example, .wrapper.type-example > .wrapper-title { background-color: rgba(101,31,255,.1); } .wrapper.type-example > .wrapper-title { border-bottom-color: rgba(101,31,255,.1); } .info.type-example > .info-content::before, .wrapper.type-example > .wrapper-title::before { color: #651fff; content: "π‘"; } /* 8. quote */ .info.type-quote { border-left-color: #9e9e9e; } .info.type-quote, .wrapper.type-quote, .wrapper.type-quote > .wrapper-title { background-color: hsla(0,0%,62%,.1); } .wrapper.type-quote > .wrapper-title { border-bottom-color: hsla(0,0%,62%,.1); } .info.type-quote > .info-content::before, .wrapper.type-quote > .wrapper-title::before { color: #9e9e9e; content: "β"; } /* 9. important */ .info.type-important { border-color: rgba(255,23,68,.1); border-left-color: #ff1744; } .info.type-important, .wrapper.type-important, .wrapper.type-important > .wrapper-title { background-color: rgba(255,23,68,.1); } .wrapper.type-important > .wrapper-title { border-bottom-color: rgba(255,23,68,.1); } .info.type-important > .info-content::before, .wrapper.type-important > .wrapper-title::before { color: #ff1744; content: "!"; } /* Info container */ .info-title { margin: -.4rem -.6rem .4rem -.6rem; padding: .4rem .6rem .4rem .6rem; font-weight: 700; } .info-content { margin: 0; padding: .4rem .6rem .4rem 4.4rem; /* font-weight: 700; */ } .info > .info-content::before { position: absolute; left: 1rem; top: .4rem; color: #939a45; /* font-weight: bold; */ font-size: 3rem; content: "i"; height: 3rem; width: 3rem; text-align: center; line-height: normal; font-family: "Times New Roman", Times, serif; /* opacity: 0.4; */ } }
7. Sanitization
<?php $sanitize = function($value, $filter) { switch ($filter) { case 'color': if (preg_match('/^( (\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}))| # color value (rgb\(([0-9]{1,3}%?,){2}[0-9]{1,3}%?\)) # rgb triplet )$/x', $value)) { return $value; } break; case 'width': if (preg_match('/^\d*\.?\d+(%|px|em|ex|pt|cm|mm|pi|in)$/', $value)) { return $value; } break; case 'class': if (preg_match('/[^A-Za-z0-9_-]/', $value)) { return $value; } break; } };
8. Wrapper
text
shade
box
box | shade | page | text | |
---|---|---|---|---|
type | + | + | β | - |
title | + | + | β | - |
alignment | + | β1 | β2 | + |
clear | + | + | β | β |
width | + | β1 | + | β3 |
column | β | + | β | + |
frame | + | + | β | β |
automatic line feed | + | + | + | β |
1 This option does not make sense, because the width of the block is always equal to the width of the page.
2 Only to the left.
3 If you don't put the line feeds yourself, the block width is fixed by the engine at approximately 90% of the page width.
What exactly is the purpose of the page wrapper in comparison to the text wrapper?
- visualize
8.1. box
<?php /* %%(Formatter wrapper="box" [wrapper_align="left | center | right"] [wrapper_width="pixel"] [wrapper_title="Title"] [wrapper_type="default | error | example | important | note | question | quote | success | warning"] [col=2|3|4|5] [clear]) content %% */ $align_class = ''; $type_class = ''; $types = ['default', 'error', 'example', 'important', 'note', 'question', 'quote', 'success', 'warning']; // defaults $options['wrapper_type'] ??= 'default'; $options['wrapper_title'] ??= null; $options['wrapper_align'] ??= 'right'; $options['wrapper_width'] ??= 250; $options['clear'] ??= false; $options['col'] ??= false; if (in_array($options['wrapper_align'], ['center', 'left', 'right'])) { // wrapper-* align in wacko.css $align_class = ' wrapper-' . $options['wrapper_align']; } if (in_array($options['wrapper_type'], $types)) { // wrapper type-* in wacko.css $type_class = ' type-' . $options['wrapper_type']; } $col_class = $options['col'] ? ' wrapper-col' . (int) $options['col'] : ''; // output wrapper $tpl->type = $type_class; $tpl->align = $align_class; $tpl->col = $col_class; $tpl->width = (int) $options['wrapper_width']; $tpl->t_title = $options['wrapper_title'] ?? null; $tpl->text = $text; if ($options['clear']) { $tpl->clear = true; }
[ === main === ] <ignore> <aside class="wrapper[ ' type ' ][ ' align ' ][ ' col ' ]" style="width: [ ' width ' ]px;"> [= t _ = <p class="wrapper-title">[ ' title | e ' ]</p> =] <div class="wrapper-content"> [ ' text // <-- no indention for embeded pre '] </div> </aside> [= clear _ = [ ' nonstatic ' ] <span class="clearfix"></span> =] </ignore>
8.2. shade
<?php /* %%(Formatter wrapper="shade" [wrapper_title="Title"] [wrapper_type="default | error | example | important | note | question | quote | success | warning"] [col=2|3|4|5]) content %% */ $type_class = ''; $types = ['default', 'error', 'example', 'important', 'note', 'question', 'quote', 'success', 'warning']; // defaults $options['wrapper_type'] ??= 'default'; $options['wrapper_title'] ??= null; $options['col'] ??= false; if (in_array($options['wrapper_type'], $types)) { // wrapper type-* in wacko.css $type_class = ' type-' . $options['wrapper_type']; } $col_class = $options['col'] ? ' wrapper-col' . (int) $options['col'] : ''; // output wrapper $tpl->type = $type_class; $tpl->col = $col_class; $tpl->t_title = $options['wrapper_title'] ?? null; $tpl->text = $text;
[ === main === ] <ignore> <div class="wrapper[ ' type ' ]"> [= t _ = <p class="wrapper-title">[ ' title | e ' ]</p> =] <div class="wrapper-content[ ' col ' ]"> [ ' text // <-- no indention for embeded pre '] </div> </div> </ignore>
8.3. page
<?php /* %%(Formatter wrapper="page" [wrapper_width=200]) content %% */ // defaults $options['wrapper_width'] ??= '800'; // output wrapper $tpl->width = (int) $options['wrapper_width']; $tpl->text = $text;
[ === main === ] <ignore> <div style="width: [ ' width ' ]px;"> [ ' text // <-- no indention for embeded pre '] </div> </ignore>
8.4. text
<?php /* %%(Formatter wrapper="text" [wrapper_align="left | center | right | justify"] [col=2|3|4|5] [clear]) content %% */ $align_class = ''; // defaults $options['wrapper_align'] ??= 'left'; $options['clear'] ??= false; $options['col'] ??= false; if (in_array($options['wrapper_align'], ['center', 'justify', 'left', 'right'])) { if ($options['wrapper_align'] != 'justify') { // wrapper-* align in wacko.css $align_class = 'wrapper-' . $options['wrapper_align']; } $text_align = ' style="text-align: ' . $options['wrapper_align'] . ';"'; } $col_class = $options['col'] ? ' wrapper-col' . (int) $options['col'] : ''; // output wrapper $tpl->align = $align_class; $tpl->txtalign = $text_align; $tpl->col = $col_class; $tpl->text = $text; if ($options['clear']) { $tpl->clear = true; }
[ === main === ] <ignore> <div class="[ ' align ' ][ ' col ' ]"[ ' txtalign ' ]> [ ' text // <-- no indention for embeded pre '] </div> [= clear _ = [ ' nonstatic ' ] <span class="clearfix"></span> =] </ignore>