Ferreteria/v0.6/clade/boot/Screen/Cmd

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | boot‎ | Screen
Jump to navigation Jump to search
clade: boot\Screen\Cmd
Clade Family
Screen Cmd (none)
Clade Aliases
Alias Clade
Base* [ca,i] boot\Screen
ElementClass IO\O\View\TTY\Screen
FallStyleClass Config\Style\General\StandardCmd
Subpages

About

  • Purpose: environment class variant for CLI

History

  • 2024-05-27 Moving this stuff into loaders/screen/, because it keeps being unavailable for the autoloader.
    • xTODO: The table stuff should be in another class. Not sure how to structure this yet. Leaving it here for now.
  • 2025-11-02 for future reference -- checkmark: [✓]

Code

interface iCmd extends BaseIface {}
class cCmd extends BaseClass implements iCmd {
    // GENERAL
    const ESC = "\e";
    // COLOR VALUES:
    const COL_BLK_FG = 30;
    const COL_BLK_BG = 40;
    const COL_WHT_FG = 37;
    const COL_WHT_BG = 47;

    const COL_GRN_FG = 32;
    const COL_GRN_BG = 42;
    const COL_YEL_FG = 33;
    const COL_YEL_BG = 43;
    const COL_BLU_FG = 34;
    const COL_BLU_BG = 44;
    const COL_RESET_FG = 39;  // default foreground
    const COL_RESET_BG = 49;  // default background

    // ++ CONFIG ++ //

    protected function ElementClass() : string { return ElementClass::class; }
    protected function FallbackStyleClass() : string { return FallStyleClass::class; }

    // -- CONFIG -- //
    // ++ MARKS ++ //

    protected function MarkForBold(bool $bOn) : string { return $bOn ? "\e[1m" : "\e[22m"; }
    protected function MarkForItal(bool $bOn) : string { return $bOn ? '' : ''; }
    protected function MarkForSmall(bool $bOn) : string { return $bOn ? '' : ''; }

    // -- MARKS -- //
    // ++ API ++ //

    // text formatting

    public function NewLine() : string { return "\n"; }
    public function LineBreaks(string $s) : string { return $s; }
    public function BoldIt(?string $s) : string { return "\e[1m$s\e[22m"; }
    public function ItalIt(?string $s) : string { return $s; }
    public function SmallIt(?string $s) : string { return "($s)"; }
    public function UBarIt(?string $s) : string {
        $nLen = $this->VisibleLength($s);
        return $s.CRLF.str_repeat('-',$nLen);   // TODO: make '-' configurable via a style
    }

    // colors
    public function BlueIt(string $s) : string { return "\e[34m$s\e[0m"; }
    public function GreenIt(string $s) : string { return "\e[32m$s\e[0m"; }
    public function YellowIt(string $s) : string { return "\e[93m$s\e[0m"; }

    // styles
    public function DebugIt(string $s) : string { return "\e[100m\e[97m(\e[93mD\e[97m\e[22m) \e[30m$s\e[0m"; }
    public function InfoIt(string $s) : string {
      return
         EscCol(self::COL_GRN_BG)
        .EscCol(self::COL_WHT_FG)
        .'('
        .EscCol(self::COL_BLK_FG)
        .'I'
        .EscCol(self::COL_WHT_FG)
        .')'
        .EscCol(self::COL_RESET_BG)
        .' '
        .EscCol(self::COL_GRN_FG)
        .$s
        .EscCol(0)
        ;
    }
      #"\e[42m(\e[30mI\e[22m)\e[0m ".$this->YellowIt($s); }
    public function FaintIt(string $s) : string { return "\e[2m$s\e[22m"; }
    public function XMLTagIt(string $s) : string { return $this->BlueIt($this->BoldIt('<')).$s.$this->BlueIt($this->BoldIt('>')); }

    // 2021-08-23 Written but not tested.
    public function TitleIt(string $s) : string {
        $nLen = strlen($s);
        $sLine = '+'.str_repeat('-',$nLen+2).'+';
        $CRLF = $this->NewLine();
        return $CRLF.$sLine.$CRLF."| $s |".$CRLF.$sLine.$CRLF;
    }
    public function ErrorIt(string $s) : string { return "\e[1;31m$s\e[0m"; }
    // experimental in TTY
    public function LinkIt(string $sText, string $sURL) : string { return "\e]8;;$sURL\e\\$sText\e]8;;\e\\"; }
    // 2021-09-24 This will need improving. Not tested.
    public function BoxIt(string $s) : string { return $s; }

    // TODO 2025-02-19: replace this with a Style system call
    public function InlineClass(string $sText, string $sClass) : string { return $sText; }


    // There really isn't any CLI equivalent, but maybe we can pretty this up more later.
    public function HideDrop(string $sSummary, string $sContent) : string {
        $ftSumm = $this->BlueIt($sSummary);
        $ftDash = $this->BoldIt('====');
        return "\n$ftDash [+] $ftSumm $ftDash\n$sContent\n$ftDash [-] $ftSumm $ftDash\n";
    }
    // fixed-pitch / linebreaks: CLI is always in that mode, so do nothing
    public function OpenFixed() : string { return "\n"; }
    public function ShutFixed() : string { return "\n"; }
    public function FixPitchIt(string $s) : string { return "'"`UNIQ--pre-00000001-QINU`"'"; }
    public function NewLineIt(string $s) : string { return $s; }  // no conversion needed

    // bulk text formatting

    // crude indentation
    public function MakeList(string $s) : string { return str_replace("\n","\n  ",$s); }

    // graphic elements

    public function HorizLine() : string { return str_repeat('-',40); }

    // characters

    public function LeftArrow() : string { return '<-'; }
    public function RightArrow() : string { return '->'; }

    // markup

    // NOTE: Not to be confused with VisibleLength()
    public function StripMarkup(string $s) : string { return $s; }
    /**
      ACTION: write the output to a temp file, then use an external program to render it for TTY.
      HISTORY:
        2024-08-13 written; would eventually like better rendering...
    */
    public function RenderHTML(string $ht) : string {
        $crlf = $this->NewLine();
        // get temp filename to use for output
        $fnRaw = tempnam('/tmp','woozalia');
        $fsRaw = $fnRaw.'.html';
        // write the output to the temp file
        $ok = file_put_contents($fsRaw,$ht);
        if ($ok) {
            $fsRend = $fnRaw.'.txt';
            $sCmd = "html2text -o '$fsRend' '$fsRaw'";
            // 2024-08-13 WORKING HERE
            $ok = exec($sCmd,$arRes);
            if ($ok) {
                $sOut = implode($crlf,$arRes);
            } else {
                echo $this->ErrorIt('Error: could not re-render tempfile ')." [$fsRaw] to [$fsRend].".$crlf;
                echo $ht; // echo the rest of the display without rendering
                die();
            }
        } else {
            echo $this->ErrorIt('Error: could not write to tempfile ')." [$fsRaw]".$crlf;
            echo $ht; // echo the rest of the display without rendering
            die();
        }
        return $sOut;
    }

    // -- API -- //
    // ++ TTY-only ++ //

    public function VisibleLength(string $sFull) : int {
        // TODO
        $nViz = 0;
        $dxFi = 0;

        do {
            // Get postion of next ESC sequence, if any:
            $dxSt = strpos($sFull,"\e[",$dxFi);
            if (is_int($dxSt)) {
                // ESC sequence-start found
                // Get the number of [visible] characters since the end of the previous ESC sequence:
                $nViz += ($dxSt-$dxFi);

                #$sDbg = ($nViz > 0) ? substr($sFull,$dxFi,$nViz) : '';
                #echo " - dxFi=[$dxFi] dxSt=[$dxSt] nViz=[$nViz] substr=[$sDbg]\n";

                $dxFi = strpos($sFull,'m',$dxSt);

                #echo " - next dxFi=[$dxFi]\n";

                if (is_int($dxFi)) {
                    $dxFi++;    // skip the ending char
                    $bFnd = TRUE;
                } else {
                    #echo " - No finishing mark!\n";
                    $bFnd = FALSE;
                    // This should kind of never happen...
                }
            } else {
                // No [more] start-marks to find, so add in the remaining length:
                $nViz += strlen($sFull) - $dxFi;
                $bFnd = FALSE;

                #$sDbg = ($nViz > 0) ? substr($sFull,$dxFi,$nViz) : '';
                #echo " - end-part found; dxFi=[$dxFi] nViz=[$nViz] substr=[$sDbg]\n";
            }
        } while ($bFnd);
        #echo " - nViz=[$nViz]\n";
        #echo "DASHES= [".str_repeat('-',$nViz).']'.CRLF;
        return $nViz;
    }

    // ++ TTY-only (so far) ++ //

    public function ClearToEOL() : string { return self::ESC.'[0J'; }

    // -- TTY-only ++ //

}