#!/usr/bin/perl
######################################################################
# eg/mn/mb_practical.pl - тэмдэгт эвдэлгүйгээр тогтмол баганаар тайрах
#
# Энэ жишээ юуг харуулж байна (жижиг бодит ажил):
#   Тогтмол баганатай гаралтын тулд Shift_JIS мөрийг тогтмол DISPLAY
#   WIDTH хүртэл тайрах бөгөөд хагас өргөний тэмдэгтийг 1 багана,
#   бүтэн өргөний тэмдэгтийг 2 багана гэж тоолж (сонгодог 1:2 харьцаа),
#   хоёр байтын тэмдэгтийг заагт хэзээ ч хуваахгүй.
#
# CORE-оос юугаараа ялгаатай вэ:
#   Гэнэн CORE substr(EXPR, 0, N) нь N дэх OCTET дээр тайрч, унжсан lead
#   byte үлдээж болно -- эвдэрсэн тэмдэгтийн хагас. Энд бид mb::split('')
#   ашиглан бүтэн тэмдэгтүүдийг гүйлгэж, тэмдэгт бүрийн өргөнийг байтын
#   уртаар нь хэмжинэ (1 байт -> 1 багана, 2 байт -> 2 багана), төсвөөс
#   хэтрэхээс өмнө зогсоно. mb::length() нь үр дүн бүхэл тооны тэмдэгт
#   болохыг баталгаажуулна.
#
# Эх нь US-ASCII; multibyte өгөгдөл \xHH байт escape ашиглана. Зөвхөн
# runtime интерфейс тул 5.005_03-аас дээш бүх perl дээр ажиллана.
#
#     perl eg/mn/mb_practical.pl
#
######################################################################
use strict;
use vars qw($line $budget $out $col $ch $w $aiu $octet_cut $char_cut);

use FindBin;
use lib "$FindBin::Bin/../../lib";
use mb;
mb::set_script_encoding('sjis');

# A B C дараа нь бүтэн өргөний гурван хирагана a i u дараа нь хагас өргөний хоёр катакана.
#   ASCII A B C            : тус бүр 1 багана
#   бүтэн өргөн a(\x82\xA0) i(\x82\xA2) u(\x82\xA4) : тус бүр 2 багана
#   хагас өргөн ka(\xB6) ki(\xB7)                   : тус бүр 1 багана
$line   = "ABC\x82\xA0\x82\xA2\x82\xA4\xB6\xB7";
$budget = 7;   # 7 дэлгэцийн багана хүртэл тайрах

# Тэмдэгтийн заагт аюулгүй, өргөн мэдэрдэг тайралт.
$out = '';
$col = 0;
for $ch (mb::split('', $line)) {
    $w = length($ch);        # 1 байт -> 1 багана, 2 байт -> 2 багана
    last if $col + $w > $budget;
    $out .= $ch;
    $col += $w;
}

# ABC (3 багана) + a (2) + i (2) = 7 багана; u хэтрэн гарч хасагдана, тул
# сүүлчийн хоёр байтын тэмдэгт бүтэн үлдэнэ.
print "input chars      : ", mb::length($line), "\n";        # 8
print "budget columns   : $budget\n";                        # 7
print "kept chars       : ", mb::length($out), "\n";         # 5
print "used columns     : $col\n";                           # 7
print "kept bytes       : ", length($out), "\n";             # 7

# Зөвхөн хоёр байтын өгөгдөлтэй харьцуулбал: тогтмол OCTET тоо дээр тайрах
# нь тэмдэгтийн дотор буух боломжтой. Хирагана a i u бүгд хоёр байт тул
# сондгой байтын урт нь тайралт тэмдэгтийг хуваасныг илэрхийлнэ; mb::substr
# үргэлж тэмдэгтийн заагт зогсоно (энд тэгш байтын урт).
$aiu       = "\x82\xA0\x82\xA2\x82\xA4";
$octet_cut = substr($aiu, 0, 3);        # a + унжсан lead byte
$char_cut  = mb::substr($aiu, 0, 1);    # яг a
print "CORE substr 3oct : ", length($octet_cut), " bytes (odd -> split)\n"; # 3
print "mb::substr 1char : ", length($char_cut),  " bytes (whole char)\n";   # 2

exit 0;
