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);
}


  1. extend the wrappers box and shade
  2. add formatter for callout
  3. arguments for formatter and wrapper
    1. type
    2. title
    3. icon
    4. col
  4. add prefix wrapper_ for wrapper arguments

Wrappers were parsed after the highlighter...


Formatter

  1. %%(info type="warning" title="Warning") Formatter info.%%

Wrapper

  1. %%(wacko wrapper="shade" wrapper_type="warning" wrapper_title="Warning") Formatter wacko with shade wrapper.%%

1. Issues

  1. 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
  2. CSS for print and wordprocessor
  3. Reset body_r after changing CSS class for wrapper to .wrapper and .wrapper-content
  4. 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">
  5. CSS: define min-height for both containers
  6. use type to assign style only to paragraph <p class="type-warning">
  7. Unicode icon versus SVG icon
  8. Paragrafica & Formatters: <ignore> terminator versus auto-paragraphs
  9. it is too colorful, reduce and simplify color usage
  10. 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="note | warning | error | important"]
        [title="Title"]
        [icon=0|1])
        [style="no use"])
    content
    % %
*/

$style_class    'info';
$type_class        '';
$types            = ['default''error''example''important''note''question''quote''success''warning'];

if (!isset(
$options['type']))        $options['type']    = 'default';
if (!isset(
$options['title']))        $options['title']    = '';
if (!isset(
$options['icon']))        $options['icon']    = 1;
if (!isset(
$options['style']))        $options['style']    = false;

if (
in_array($options['type'], $types))
{
    
// info type-* in wacko.css
    
$type_class ' type-' $options['type'];
}

$title $options['title'] ?? null;

echo    
'<ignore><div class="' $style_class $type_class '">' "\n";
echo    (
$options['icon'] ? '<div class="info-content">' '') . "\n" .
        (
$title
            
'<p class="info-title">' Ut::html($title) . '</p>' "\n"
            
'');
include 
Ut::join_path(FORMATTER_DIR'wiki.php');
echo    (
$options['icon'] ? '</div>' '') . "\n";
echo    
"</div></ignore>\n";

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


Color picker tool

4. Types

  1. note, tip, hint, nota bene *
  2. abstract, summary
  3. error, failure, fail
  4. important, attention
  5. success
  6. question, help, faq 
  7. warning, caution, attention, danger
  8. issue, bug 
  9. example, snippet
  10. 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="note | warning | error | important"]
        [col=2|3|4|5]
        [clear])
    content
    % %
*/

$align_class    '';
$type_class        '';
$types            = ['default''error''example''important''note''question''quote''success''warning'];

if (!isset(
$options['wrapper_type']))    $options['wrapper_type']    = 'default';
if (!isset(
$options['wrapper_title']))    $options['wrapper_title']    = null;
if (!isset(
$options['wrapper_align']))    $options['wrapper_align']    = 'right';
if (!isset(
$options['wrapper_width']))    $options['wrapper_width']    = 250;
if (!isset(
$options['clear']))            $options['clear']            = false;
if (!isset(
$options['col']))            $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'] : '';
$title        $options['wrapper_title'] ?? null;

// output wrapper
echo    '<ignore><aside class="wrapper' $type_class $align_class $col_class '" style="width: ' . (int) $options['wrapper_width'] . 'px;">' "\n" .
            (
$title
                
'<p class="wrapper-title">' Ut::html($title) . '</p>' "\n"
                
'') .
            
'<div class="wrapper-content">' "\n" .
                
$text.
            
"</div>\n" .
        
"</aside></ignore>\n";

if (
$options['clear'])
{
    echo 
'<span class="clearfix"></span>';
}

8.2. shade


<?php

/*
    % %(Formatter
        wrapper="shade"
        [wrapper_title="Title"]
        [wrapper_type="note | warning | error | important"]
        [col=2|3|4|5])
    content
    % %
*/

$type_class        '';
$types            = ['default''error''example''important''note''question''quote''success''warning'];

if (!isset(
$options['wrapper_type']))    $options['wrapper_type']    = 'default';
if (!isset(
$options['wrapper_title']))    $options['wrapper_title']    = null;
if (!isset(
$options['col']))            $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'] : '';
$title        $options['wrapper_title'] ?? null;

// output wrapper
echo    '<ignore><div class="wrapper' $type_class '">' "\n" .
            (
$title
                
'<p class="wrapper-title">' Ut::html($title) . '</p>' "\n"
                
'') .
            
'<div class="wrapper-content' $col_class '">' "\n" .
                
$text .
            
"</div>\n" .
        
"</div></ignore>\n";

8.3. page


<?php

/*
    % %(Formatter
        wrapper="page"
        [wrapper_width=200])
    content
    % %
*/

if (!isset($options['wrapper_width'])) $options['wrapper_width'] = '800';

// output wrapper
echo    '<div style="width: ' . (int) $options['wrapper_width'] . 'px">' "\n" .
            
$text .
        
"</div>\n";

8.4. text


<?php

/*
    % %(Formatter
        wrapper="text"
        [wrapper_align="left | center | right | justify"]
        [col=2|3|4|5]
        [clear])
    content
    % %
*/

$align_class '';

if (!isset(
$options['wrapper_align']))    $options['wrapper_align']    = 'left';
if (!isset(
$options['clear']))            $options['clear']            = false;
if (!isset(
$options['col']))            $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
echo    '<ignore><div class="' $align_class $col_class '"' $text_align '>' "\n" .
            
$text .
        
"</div></ignore>\n";

if (
$options['clear'])
{
    echo 
'<span class="clearfix"></span>';
}


9. Links

  1. Forum: Callouts