Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created March 26, 2017 13:22
Show Gist options
  • Save zr-tex8r/511651aa308e85edd373c2d40d8d7de7 to your computer and use it in GitHub Desktop.
Save zr-tex8r/511651aa308e85edd373c2d40d8d7de7 to your computer and use it in GitHub Desktop.
LaTeXで斬新な表現をするやつ
%%
%% This is file 'tczeeen.sty'.
%%
%% Copyright (c) 2017 Takayuki YATO (aka. "ZR")
%% GitHub: https://github.com/zr-tex8r
%% Twitter: @zr_tex8r
%%
%% This package is distributed under the MIT License.
%%
%% package declaration
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{tczeeen}[2017/03/26 v0.2]
\def\tcqzn@pkgname{tczeeen}
\providecommand\bxDebug[1]{}
%--------------------------------------- environment check
%% packages
\RequirePackage{pdftexcmds}[2009/09/23]% v0.6
\RequirePackage{ifxetex,ifluatex}
%% switches
\newif\iftcqzn@ptex
\newif\iftcqzn@luatexja
\newif\iftcqzn@tate@avail
%% engine check
\pdf@isprimitive\kanjiskip\kanjiskip{\tcqzn@ptextrue}{}
\@tempswafalse
\ifxetex \@tempswatrue \fi
\ifluatex \@tempswatrue \fi
\iftcqzn@ptex \@tempswatrue \fi
\if@tempswa\else
\PackageError\tcqzn@pkgname
{The engine in use is not supported}
{Package loading is aborted.\MessageBreak\@ehc}
\expandafter\endinput\fi\relax
%--------------------------------------- package options
% driver options
\DeclareOption{dvips}{%
\PassOptionsToPackage{dvips}{graphicx}%
\PassOptionsToPackage{dvips}{trimclip}}
\DeclareOption{dvipdfmx}{%
\PassOptionsToPackage{dvipdfm}{graphicx}%
\PassOptionsToPackage{dvipdfm}{trimclip}}
% dispatch
\ProcessOptions\relax
%--------------------------------------- general
%% error messages
\def\tcqzn@err@nschr{%
\PackageError\tcqzn@pkgname
{The argument is not a single character}%
{\@eha}}
\def\tcqzn@err@ukchr{%
\PackageError\tcqzn@pkgname
{The character cannot be used with \string\zeeen}%
{\@eha}}
\def\tcqzn@err@ivprp#1{%
\PackageError\tcqzn@pkgname
{The argument has bad format:\MessageBreak
\space\space'#1'}%
{\@eha}}
\def\tcqzn@err@ivrng#1#2{%
\PackageError\tcqzn@pkgname
{Invalid range: #1, #2}%
{\@eha}}
%% unique tokens
\def\tcqzn@end{\tcqzn@end@}
\def\tcqzn@mt{\tcqzn@mt@}
\let\tcqzn@mk\noindnet
%% switches
\newif\iftcqzn@ok
%% variables
\newcount\tcqzn@cntr
\newdimen\tcqzn@dimr
\newbox\tcqzn@boxa
%% \tcqzn@csletcs{<csname1>}{<csname2>}
\def\tcqzn@csletcs#1#2{%
\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname}
%% \tcqzn@cond\if...\fi{<true>}{<false>}
\@gobbletwo\if\if \def\tcqzn@cond#1\fi{%
#1\expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi}
%% \tcqzn@read@real{<text>}
\def\tcqzn@read@real#1{%
\tcqzn@dimr\maxdimen
\ifx\tcqzn@mt#1\tcqzn@mt\else
\afterassignment\tcqzn@read@real@a\tcqzn@dimr=#1\p@\tcqzn@mk
\fi}
\def\tcqzn@read@real@a#1\tcqzn@mk{%
\ifx\tcqzn@mt#1\tcqzn@mt\else \tcqzn@dimr\maxdimen \fi}
%% \tcqzn@get@code{<char>}
\def\tcqzn@get@code#1{%
\tcqzn@cntr\m@ne
\futurelet\tcqzn@tok\tcqzn@get@code@a#1\tcqzn@end}
\def\tcqzn@get@code@a{%
\expandafter\tcqzn@get@code@b\meaning\tcqzn@tok.....\tcqzn@end}
\def\tcqzn@get@code@b#1#2#3#4#5#6\tcqzn@end{%
\tcqzn@cond\expandafter\ifx\csname
tcqzn@ic/#1#2#3#4#5\endcsname\relax\fi{%
\tcqzn@get@code@c
}{%else
\tcqzn@get@code@d
}}
\def\tcqzn@get@code@c#1\tcqzn@end{}
\def\tcqzn@get@code@d#1#2\tcqzn@end{%
\tcqzn@cond\ifx\tcqzn@mt#2\tcqzn@mt\fi{%
\tcqzn@cntr=`#1\relax
}{}}
\tcqzn@csletcs{tcqzn@ic/thele}{@ne}
\tcqzn@csletcs{tcqzn@ic/thech}{@ne}
\tcqzn@csletcs{tcqzn@ic/kanji}{@ne}
%--------------------------------------- engine dependency
%% \iftcqzn@tdir
% It is either \iftdir or \iffalse.
\tcqzn@csletcs{iftcqzn@tdir}{\iftcqzn@ptex iftdir\else iffalse\fi}
%% \tcqzn@code{<jis-hex>}{<ucs-hex>}
\iftcqzn@ptex
\def\tcqzn@code#1#2{\jis"#1\tcqzn@spaces}
\else
\def\tcqzn@code#1#2{\number"#2\tcqzn@spaces}
\fi
\edef\tcqzn@spaces{\space\space}
%% \tcqzn@zspc
\chardef\tcqzn@zspc=\tcqzn@code{2121}{3000}
%% \tcqzn@if@tate{<tate>}{<yoko>}
\let\tcqzn@if@tate\@secondoftwo
%% \tcqzn@initialize
\def\tcqzn@initialize{%
\global\let\tcqzn@initialize\relax
\ifluatex
\@ifpackageloaded{luatexja}{\global\tcqzn@luatexjatrue}{}%
\fi
\iftcqzn@ptex
\global\tcqzn@tate@availtrue
\gdef\tcqzn@if@tate{\tcqzn@cond\iftcqzn@tdir\fi}%
\else\iftcqzn@luatexja
\global\tcqzn@tate@availtrue
\global\chardef\tcqzn@luatexja@tate=3
\gdef\tcqzn@if@tate{\tcqzn@cond
\ifnum\ltjgetparameter{direction}=\tcqzn@luatexja@tate\fi}%
\fi\fi}
\AtBeginDocument{%
\tcqzn@initialize}
%--------------------------------------- build characters
%% packages
\RequirePackage{graphicx}% avoids trimclip's messing with drivers...
\RequirePackage{trimclip}
%% variables
\newdimen\tcqzn@zw
\let\tcqzn@char\relax
\let\tcqzn@rprs\relax
\let\tcqzn@rpre\relax
%% \tcqzn@put@fragment
\def\tcqzn@put@fragment#1#2{%
\tcqzn@if@tate{% tate
\@tempdima\p@ \advance\@tempdima-#2\p@
\edef\tcqzn@tmpa{\z@\space \strip@pt\@tempdima\tcqzn@zw\space}%
\@tempdima\p@ \advance\@tempdima-#1\p@
\edef\tcqzn@tmpa{\tcqzn@tmpa\tcqzn@zw\space \strip@pt\@tempdima\tcqzn@zw}%
\edef\tcqzn@tmpa{%
% NB. \clipbox must be invoked in yoko direction.
\hbox{\hbox{\yoko
\noexpand\clipbox*{\tcqzn@tmpa}{\hbox{\tate\noexpand\tcqzn@char}}}}%
}\tcqzn@tmpa
}{% yoko
\setbox\tw@\hbox{\tcqzn@char}%
\edef\tcqzn@tmpa{%
\noexpand\clipbox*{#1\tcqzn@zw\space -\the\dp\tw@\space
#2\tcqzn@zw\space \the\ht\tw@}{\noexpand\tcqzn@char}%
}\tcqzn@tmpa
}}
%% \tcqzn@build@char{<length>}{<char>}
\def\tcqzn@build@char#1#2{%
\tcqzn@get@code{#2}%
\ifnum\tcqzn@cntr<\z@ \tcqzn@err@nschr
\else
\setlength\tcqzn@dimr{#1}%
\ifdim\tcqzn@dimr<\tcqzn@zw \tcqzn@dimr\tcqzn@zw \fi
\edef\tcqzn@char{#2}%
\tcqzn@csletcs{tcqzn@tmpa}{tcqzn@pr/\tcqzn@if@tate{t}{y}/\the\tcqzn@cntr}%
\ifx\tcqzn@tmpa\relax
\tcqzn@err@ukchr
\tcqzn@char % fallback output
\else
\expandafter\tcqzn@build@char@a\tcqzn@tmpa
\@tempdima\tcqzn@rpre\tcqzn@zw \advance\@tempdima-\tcqzn@rprs\tcqzn@zw
\advance\tcqzn@dimr-\tcqzn@zw \advance\tcqzn@dimr\@tempdima
\@tempdimb\tcqzn@dimr \advance\@tempdimb\@tempdima
\advance\@tempdimb-\@ne\@ne \divide\@tempdimb\@tempdima
\tcqzn@cntr\@tempdimb
\tcqzn@put@fragment{0}{\tcqzn@rprs}%
\savebox\tcqzn@boxa{\tcqzn@put@fragment{\tcqzn@rprs}{\tcqzn@rpre}}%
\makebox[\tcqzn@dimr][s]{%
\@whilenum{\tcqzn@cntr>\z@}\do{%
\advance\tcqzn@cntr\m@ne
\usebox\tcqzn@boxa\hss}%
\unskip}%
\tcqzn@put@fragment{\tcqzn@rpre}{1}%
\fi
\fi}
\def\tcqzn@build@char@a#1#2{%
\def\tcqzn@rprs{#1}\def\tcqzn@rpre{#2}}
%--------------------------------------- user interface
%% constants
\def\tcqzn@rp@limit{0.001}
%% variables
\let\tcqzn@idx\relax
\let\tcqzn@val\relax
%%<*> \zeeenyokoprop{<char>}{<r1>,<r2>}
\@ifdefinable{\zeeenyokoprop}{%
\DeclareRobustCommand*\zeeenyokoprop{%
\tcqzn@set@prop@chr{y}}}
%%<*> \zeeentateprop{<char>}{<r1>,<r2>}
\@ifdefinable{\zeeentateprop}{%
\DeclareRobustCommand*\zeeentateprop{%
\tcqzn@set@prop@chr{t}}}
\def\tcqzn@set@prop@chr#1#2{%
\tcqzn@get@code{#2}%
\tcqzn@cond\ifnum\tcqzn@cntr<\z@\fi{%
\tcqzn@err@nschr
\@gobble
}{%else
\edef\tcqzn@idx{#1/\the\tcqzn@cntr}%
\tcqzn@set@prop
}}
%%<+> \ZeeenSetProp{<dir>}{<jis-hex>}{<ucs-hex>}{<r1>,<r2>}
\@ifdefinable{\ZeeenSetProp}{%
\DeclareRobustCommand*\ZeeenSetProp[3]{%
\tcqzn@cntr=\tcqzn@code{#2}{#3}%
\edef\tcqzn@idx{#1/\the\tcqzn@cntr}%
\tcqzn@set@prop}}
%% \tcqzn@set@prop{<r1>,<r2>}
\def\tcqzn@set@prop#1{%
\edef\tcqzn@tmpa{#1}\tcqzn@okfalse
\expandafter\tcqzn@set@prop@a\tcqzn@tmpa,\tcqzn@mk,,\tcqzn@end
\iftcqzn@ok
\tcqzn@check@range \iftcqzn@ok
\edef\tcqzn@tmpa{\noexpand\@namedef{tcqzn@pr/\tcqzn@idx}{\tcqzn@val}%
}\tcqzn@tmpa
\else \expandafter\tcqzn@err@ivrng\tcqzn@val
\fi
\else \tcqzn@err@ivprp{#1}%
\fi}
\def\tcqzn@set@prop@a#1,#2,#3,#4\tcqzn@end{%
\ifx\tcqzn@mk#3%
\tcqzn@oktrue \tcqzn@read@real{#1}%
\ifdim\tcqzn@dimr<\z@ \tcqzn@okfalse \fi
\ifdim\tcqzn@dimr=\maxdimen \tcqzn@okfalse \fi
\edef\tcqzn@val{{\strip@pt\tcqzn@dimr}}%
\tcqzn@read@real{#2}%
\ifdim\tcqzn@dimr<\z@ \tcqzn@okfalse \fi
\ifdim\tcqzn@dimr=\maxdimen \tcqzn@okfalse \fi
\edef\tcqzn@val{\tcqzn@val{\strip@pt\tcqzn@dimr}}%
\fi}
%% \tcqzn@check@range
\def\tcqzn@check@range{%
\expandafter\tcqzn@check@range@a\tcqzn@val}
\def\tcqzn@check@range@a#1#2{%
\tcqzn@oktrue
\ifdim#2\p@>\p@ \tcqzn@okfalse \fi
\@tempdima#2\p@ \advance\@tempdima-#1\p@ \advance\@tempdima1sp
\ifdim\@tempdima<\tcqzn@rp@limit\p@ \tcqzn@okfalse \fi}
%%<*> \zeeen{<length>}{<char>}
\@ifdefinable{\zeeen}{%
\newcommand*\zeeen[2]{%
\tcqzn@zspc
\tcqzn@initialize
\begingroup
\setbox\z@\hbox{\tcqzn@zspc}\tcqzn@zw\wd\z@
\kern-\tcqzn@zw
\tcqzn@build@char{#1}{#2}%
\kern-\tcqzn@zw
\endgroup
\tcqzn@zspc}}
%--------------------------------------- initial setup
\ZeeenSetProp{t}{4134}{5168}{.540,.570}% cjk ideograph 'zen'
\ZeeenSetProp{y}{213C}{30FC}{.400,.600}% prolonged sound mark
\ZeeenSetProp{t}{213C}{30FC}{.400,.600}% prolonged sound mark
\ZeeenSetProp{y}{213D}{2014}{.250,.750}% em dash
\ZeeenSetProp{t}{213D}{2014}{.250,.750}% em dash
\ZeeenSetProp{y}{213D}{2015}{.250,.750}% quotation dash
\ZeeenSetProp{t}{213D}{2015}{.250,.750}% quotation dash
%--------------------------------------- done
\endinput
%% EOF
% pLaTeX文書
\documentclass[dvipdfmx,a4paper]{jsarticle}
\usepackage{plext}
\usepackage{tczeeen}
\setlength{\parindent}{0zw}
\begin{document}
\parbox<t>{5zw}{% 縦組みの例1
包みの中も
\zeeen{4zw}{全}部
\par\bigskip
\sffamily
包みの中も
\zeeen{4zw}{全}部}
\quad
\parbox<t>{7zw}{% 縦組みの例2
すご\zeeen{3zw}{ー}い!}
{\sffamily % 横組みの例
すご\zeeen{5zw}{ー}い!}
% 適切なパラメタを設定すれば任意の文字に適用できる
\par\bigskip
\zeeenyokoprop{一}{0.40,0.60}
\zeeenyokoprop{二}{0.40,0.60}
\zeeenyokoprop{三}{0.40,0.60}
\zeeenyokoprop{四}{0.44,0.50}
\zeeenyokoprop{五}{0.52,0.66}
\zeeen{1zw}{一}\par
\zeeen{2zw}{二}\par
\zeeen{3zw}{三}\par
\zeeen{4zw}{四}\par
\zeeen{5zw}{五}\par
\end{document}
@zr-tex8r
Copy link
Author

  • \zeeen{<長さ>}{<和文文字1つ>} でその文字を斬新に出力する。
  • 基本的に和文専用。
  • 対応エンジンは pLaTeX/upLaTeX/LuaLaTeX/XeLaTeX
  • pLaTeX/upLaTeX/LuaLaTeX の場合は縦組みにも対応。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment