白屋書房Blog

組版・縦書きサイト「白屋書房」(https://hakuoku.github.io/agakuTeX/)のブログです

約物問題の最終解決

 ZRさんが……ZRさんがもんのすごいミニパッケージを書かれました……!

LaTeX: 和文を欧文扱いして和文扱いする件 · GitHub

 これがあれば約物関連は基本何もしなくてもOKです。書いたまんま見たまんまで出力されます。余計なコマンドを打ったり不自然にベースラインをいじることもありません。夢のようだ!最後の最後でハマった三点リーダーのトラップともおさらばだ!
(間を繋げるためにダッシュを欧文扱いにすると、同じブロックに所属する三点リーダーまで欧文扱いになって左端に表示されてしまうというマヌケな手落ちがあった)

 使い方は簡単、上のリンクから飛んだ先のgistのページで「Download ZIP」ボタンを押し、ダウンロード・解凍ののち、.styのファイルを自分が組版したい文書と同じフォルダに入れ、いつもと同じように\usepackage{zrjapunct1}をプリアンブルで宣言するだけです。
 TeX Liveに含まれていない新しいパッケージや自作パッケージは、こうして同じフォルダ(ディレクトリ)に入れてusepackageするのが一番シンプルなやり方です。

 このパッケージの中身を噛み砕いて説明できるほど筆者の技術力は高くないんですが、原理としてはGeneral Punctuationを一旦全部欧文扱いにし、三点リーダーや米印など和文に戻したいものは個別に戻し、戻すだけでは解決しないダッシュやなどにトリックを凝らす、という構造のようです。
 なのでプリアンブルにおいて、\cjkcategory{}指定の中にsym04(General Punctuation)を入れないでください。このパッケージはベースがprefernoncjkモードでもprefercjkvarモードでも使えますが、せっかくパッケージが裏側で担ってくれているsym04をを明示的に自分の方で指定してしまうのは避けましょう。

 さてどんなふうに本記事に入れ込もうかな。Hugoにおける各記事のweight設定が甘かったから、もしかすると約物以降全部数字ずらすことになるのか……?やっぱりちゃんと考えながら書いたほうがいいですねorz

 あとAdvent Calenderもどうしよう。当初はサイトから横書きにも使えそうなところをピックアップして「TeXでつくる可能な限りWYSIWYGな文書」的なのを書こうかなと思っていたんですが、よく考えると今までやってきたのは縦書きに適応させたいがための小細工なので、横書きでできる項目があんまりないんですね。縦中横とか二重感嘆符とかは概念そのものが要らないし、ダブルミニュートや括弧類も普通に書けば出る。うーんボツかな……ネタ探さないと、とか言ってるうちに今日が一日ですよ

激闘TeX:rensujiのデフォルト

f:id:isaribisaitoh:20171123150309j:plain

 最初この問題に気づいてなかったんですが、グルーの項に入ったところで前後が空きすぎになっていると気がつきましたので直します。
 rensujiコマンドを定義しているplext.styを覗いてみます。

f:id:isaribisaitoh:20171123150352j:plain

 なるほどわからん
 美文書入門を紐解いてみると、『\rensujiコマンドを単純化したもの』として次の定義が載っていました。

\def\xrensuji#1{\hskip\kanjiskip\hbox to 1zw{\yoko\hss\smash{#1}\hss\rule[-0.12zw]{0zw}{1zw}}\hskip\kanjiskip}

 そこでこれを丸ままプリアンブルで\xrensujiとして定義してみるとあっさり隣の行と高さが揃いました。
 となるとこの定義の数値をいじればplextデフォルトの挙動を再現できるに違いない。さっき見た中では\rensujiskip=0.25とかいうあたりが怪しそうです。

 原始的なトライアル&エラーを繰り返し、結局は以下の数値でぴったりデフォルトと同じ高さになりました。

\def\rensuji#1{\hskip\kanjiskip\hbox to 1zw{\yoko\hss\smash{#1}\hss\rule[-0.25zw]{0zw}{1.25zw}}\hskip\kanjiskip}

 自分で自分が何をやっているのか分からないままでは悔しいので、マクロの解読を試みました。

 まず\def\rensuji#1{}。これは簡単です。「引数を1つ取るrensujiという名のコマンドを定義する」ですねね。問題は中身です。

 最初の\hskipは文字送り方向、この場合は下への空白で、シンタックス\hskip <dimen1> plus <dimen2> minus <dimen3>。今はプラスマイナスがついていないので\hskip\kanjiskipまでで、kanjiskipすなわち普通の和文文字間分の空隙を前の字との間に入れるということです(当たり前だ)。

 \hbox to 1zw{内容}で「高さ1zwの箱に内容を詰める」になります。これで「字と字の間の普通の空隙」と「1文字分のスペース」が確保されました。

f:id:isaribisaitoh:20171123150907j:plain

 次は1文字の箱に詰め込む中身です。pTeX\yoko命令で組方向を横向きに変更。これで縦中横を入れる態勢が整いました。

 水平方向に無限に伸縮するグルー\hssで次の内容を挟むことで、連数字を行の真ん中に寄せています。

f:id:isaribisaitoh:20171123150654j:plain

 でsmashがどうしてもよく分からない……高さと幅を0に潰すって何?文字の高さ・幅じゃなく純粋にhboxの大きさのみで勝負させるってこと?それとも逆で、どんな文字が入っても大丈夫にするってこと?
 どうもこれをやると配置の微調整がうまいこと行くようになるらしいんですが、明確には分かりませんでした。

 ともあれ連数字にしたい実体である#1を入れて、hssで挟んで、次の\ruleも難しかったorz

 \rule[ベースラインからの位置]{幅}{高さ}は、この通りの寸法で中身の詰まった黒いボックスを描いてくれるコマンドだそうな。
 ……今のベースラインってどこ?
 あと正負の方向もわからん。ruleはあえて幅を0にすることで『見えない支柱』になっているとのことなので、幅を持たせてみます。

f:id:isaribisaitoh:20171123150927j:plain

 今これは美文書入門の方の定義で\rule[-0.12zw]になっています。オプションを0.12と0と-0.25に変えてみます。

f:id:isaribisaitoh:20171123151027j:plainf:id:isaribisaitoh:20171123151042j:plainf:id:isaribisaitoh:20171123151057j:plain

 あれ?ボックスはそのままで文字の位置が変わった。
 ここの挙動がさっぱり分からない……直感的には、「ボックスの下端からベースラインまでの距離」を下げたらボックスもろとも下にめり込むんじゃないかと思うんだけど。
 これはつまり1zw分だけ開いている窓(\hbox)の後ろでオプション分の距離が“真の”line-heightに加算されていて、連数字の文字自体は必ず“その行幅における”ベースラインに底が揃うからこういう動きをするということでいいんでしょうか。
 プラスの値だとhboxの後ろで行の高さが下向きにプラスされて広くなっているから、数字も合わせて下に落ちる的な。(それにしては高さ1zwしかないはずの黒い箱が微動だにしないのが腑に落ちないんだけど)

 なんだか狐につままれたような感じですが元の-0.12zwに戻してやってhboxを抜け、あとは通常のkanjiskip間隔を入れてやって完了のようです。

 結局原理はよく分かってないままですが、ruleがhboxにおける連数字本体の上下の位置を決める役割を担っていることは分かりました。 あとはplextのrensujiはボックスの高さか、あるいは前後のskipに0.25を余計に設定しているから高くなりすぎるんじゃないかということもですね。

 こういうボックス周りのことを今のうちにやっておかないと多分絶対ページレイアウトの時泣く気がする。

基盤編完成です!

 やっとのことで「本文の編集・基盤編」を、まとめまで上げられました!多分後から修正箇所がポロポロ出てくるでしょうが、とりあえずこれで一段落です!!

 いやあ長かった……特に和文/欧文扱いの切り替えが長かった。自前の小説を組んでた時は分からなかったけど、十蘭の特殊文体の穴にぼこぼこはまりまくりました。
 でも怪我の功名で、どうしてもコマンドなしで何とかしたかったダッシュに道が開けたのは嬉しかったです。
 TeXは普通のプログラミング言語でやるような自動検索&置換ができない、というかものすごく難しいので、そこに突っ込むか同じくらい危険らしいフォントメトリックの沼に突っ込むかという二者択一に戦々恐々としていたんですが、うまいこと単純な手で回避できてよかった。

 しかしこれでもまだ“最低限の日本語が組めるだけ”の段階なんですよね。駆け足で更新しちゃったので、初心者向けに充分噛み砕けていないところや、逆に詳しい人から見たらガタガタなところとかがあるかもしれません。少しでも分かりづらいところがあったらぜひフィードバックお願いします。

 という感じでむしろここからが本番なんですが、年内にレイアウト編まで行けるかどうかはちょっと未定です。
 というのも「TeXLaTeX Advent Calendar 2017」に参加申し込みをしてしまったからです。

adventar.org

 ZRさんが毎年やってらっしゃるイベントで、クリスマスまでのアドベントカレンダーを一日一日TeXの記事で埋めていくというステキな企画です。今年のテーマは『TeXでつくるアレ』。現時点での私の担当は11日です。

 毎年すごく高度な話がぼんぼん飛び交っているので私なんぞが今更披露できるネタはないんですが、枯れ木も山の賑わい、ちょっとでも面白いか役に立つ記事が書けたらなーと思います。

激闘TeX:引用符をめぐって

 約物類との格闘です。このへんIPAフォントとOTFパッケージとplextとupLaTeXのデフォルトが絡み合ってパズルのようでした。
 まずは知識のないころにけっこう苦戦した〝IPAにおけるダブルミニュート〟について。
縦書きしてみよう」ではこう解説されています。

このダブルミニュートは横書きと縦書きで異なります。文字コードで言うと、横書きの左側(起こし)が CID:7608 (Unicode: U+301D)、右側(受け)がCID:7609 (Unicode: U+301F) 、縦書きの上側(起こし)が CID:7956 (Unicode: U+201C)、右側(受け)がCID:7957 (Unicode: U+201D) です。
(中略)
ただし、CID 対応でない TrueType フォント等の場合、ダブルミニュート、特に縦書き・受けのダブルミニュートが収録されていません(IPA フォントはこれに該当します)のでご注意下さい。

 そして(美文書入門にも)以下が解決策として載っていました。

\CID{7956}CID{7956}CID{7957}\CID{7957}

 ところがこれを組んでみるとこうなります。

f:id:isaribisaitoh:20171114192520j:plain

 おかしいなということでUniViewで文字の情報を確認してみると、ブロックはCJK Symbols and Punctuationでした。名前は「ダブルプライム・クォーテーションマーク」になるらしい。ダブルミニュートは和製英語のようです。

f:id:isaribisaitoh:20171114204403j:plain

 三つしかない。
 縦書きにおける正しい字形は起こし側が「右下にある上から下に払ったダブルプライム」と、受け側が「左上にある下から上に払ったダブルプライム」になるはずです。どれも違う。
 仕方ないので片っ端からタイプセットしてみます。

\UTF{301D}UTFの301D、E、F\UTF{301E}\UTF{301F}
\CID{7608}CIDの7608、7609\CID{7609}
\UTF{201C}UTFの201C、D\UTF{201D}
\UTF{201E}UTFの201E、F\UTF{201F}
\CID{7956}CIDの7956、7957\CID{7957}

f:id:isaribisaitoh:20171114192559j:plain

 やった!二番目が成功だ!あとは三番目が普通にキーボードから全角ダブルクォートを入れた時と同じですね。
 じゃあCIDの7608って何だよと思ったんですが、CID番号ってWeb上で簡単に調べられないんですねorz Adobeの公式リファレンスPDFでうまいこと探せませんでした。
 というわけで美文書入門の付録で確認すると、確かに7608と09が横書き、7956と57が縦書きのダブルプライムでした。

f:id:isaribisaitoh:20171114192731j:plain

 しかし実際にちゃんと出力されるのは横書きのはずの7608と09です。ということは、IPAex明朝ではCIDの7608=Unicodeの301Dを右に90°回転させて起こしに、左に90°回転させて受けに使っているのではないかと推測しました。7957では回転させないで使える縦書き用のグリフそのものを呼んでいる(そしてIPAには収録されていない)から豆腐になるのかと。
 そう思うとこのへんの挙動が不明です……upLaTeX+utbookで縦書き文書をタイプセットした時に、“実際には”どの字が植えられているのかがよく分かりません。UnicodeにはCJK Compatibility Formsとして縦書き用の各種カッコが収められているんですが、例えばベタ書きでカギカッコを入れた時にこの縦書き専用の形を使っているのか、それとも横書き用の起こし側を90°回して使っているのかとか。

 ちなみにCID対応フォントで組んでみるともっと分からなくなります。小塚明朝ではこうなりました。

f:id:isaribisaitoh:20171114192706j:plain

 当たり前ですがCIDのグリフに忠実に組まれました。ただし今度は一番目を回転させてるように見受けられます。301Eは持ってないのか回転できなかったのか。
 201F(Double High-Reversed-9 Quotation Mark)は収録されてないっぽいですね。そもそもどういう記号なのかがわからん。201Eはドイツ語とかで使うみたいなんですが。

 分からないことだらけですがとりあえず出力できたのでよしとしましょう。サイトのほうのマクロをプリアンブルに入れておけば\〟だけで出せるようになります。

「約物」セクション追加

全角半角・タテヨコのくだりが終わったので縦書きにおける約物の制御に入りました。
とりあえず“引用符”と、感嘆符! や英単語 etc. に自動で入るグルーと、(括弧類)の扱い方までです。
あとはダッシュだけかな?――と言ってもこれが一番根が深いんだけどorz

アクセントつきアルファベットの扱い方に比べたら大して複雑でもない問題なのに何をそんなに苦渋しているのかというと、ひとえに私の執筆方針すなわち「原稿中におけるコマンドを可能な限り減らす」のせいです。
フォントによってダッシュの間が繋がらないことは旧知の問題で、そのための解決策もとっくに出ています。\―コマンドを繋がるように定義して、文中に出てくるダッシュの頭にすべて\をつければいいんでした。

やりたくない。

原稿中にコマンド書きたくないんだよ!今回の問題すべてマクロ定義で片付けたけど本当は嫌なんだよ! それでも二重感嘆符なんかはもともと縦中横にしなければならないことは分かっていて、他の二桁の数字とかと同じと思えばまだ許せました。
ところが何故かダッシュだけは許せないんです。こう――打ちたいんです。
私自身がかなりダッシュを多用する性質だからかもしれません。大体が感情が高ぶってたりタメが入ったりするところに使うものなのでバックスラッシュがついてると水を差されたように感じるのかも。

とはいえ自動縦中横や自動ダッシュ置換を行えるほど筆者の技術力は高くありません。正直感嘆符の直後にカギカッコがくる時のグルー禁止処理だけで死ぬかと思った。それもまだベータ版だし。なんで次の字すなわちトークンをどこにもうまいこと代入できないんだ。
あーどうやったら「TeXレベルの」マクロ力強くなるんだろう……私が原著当たってないのが悪いんだけど、それでもどこかに定義済み変数(というものがあるのかどうか知らんけど要は状態を取得できるインターフェース的な)のリストとかハンディなコマンド一覧とかがあればずいぶん普通のプログラミングに近くなって助かるのにorz

しばらくは書いて書いて書き続けてTeX思考力を養うしかなさそうです。頑張ろう。

激闘TeX:ギリシャ文字とキリル文字

 アクセントと特殊記号 (2)前回の投稿までで、西ヨーロッパ諸語はなんとかなりました。次はギリシャ語とロシア語をなんとかする番なんですが、今まで避けてきたフォントの話題に触れなければならないのでまあめんどくさかったです。とりあえず私なりの理解をしたためてみます。

 pxcjkcatパッケージで「ギリシャキリル文字が欧文扱いに」なるはずのprefercjkvarモードを指定して文中にロシア語を書いてもエラーになります。

\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc}
\usepackage[prefercjkvar]{pxcjkcat}

 もう一度「UTF-8 で欧文文字を入力する ~inputenc パッケージ~」を熟読すると、これはどうやらupLaTeXそのものの挙動とinputencパッケージの働きによるものらしいです。
 でここから話が進まなくなって、先にエンコードに関する知識が必要なことが分かったので勉強しました。わけわかんないから今まで触らないようにしてたのに。・゚・(ノД`)・゚・。

 恐ろしいことにTeXには、我々が今まで一般的に使ってきたUTF-8やSHIFT-JISとは全く意味が異なるエンコーディングが存在します。
 すごくざっくり言っちゃうと、UTF-8というのは「筆者とテキストエディタが原稿を書く」ために用いているエンコード(=ファイルのエンコーディング)で、それとは別に「できたファイルを受け取ったTeX活字を並べる時に参照するエンコードというものがあって、それがかのフォントエンコーディングだというわけです。前者が入力、後者が出力と言えばいいでしょうか。
 そしてこの2つはまったく連動していません。いや和文の部分ではどっちもUnicodeだけど。TeXは欧文と和文を扱う部分が右脳と左脳のように分かれています。(語弊のある例えだけどいい言い回しが思いつかない)
 UTF-8で書かれたファイルを受け取ったupLaTeXが文を読み、最低限のアルファベットだけ欧文部分が扱い、和文部分がそれを除いたすべての文字をUnicode文字集合というひとつの巨大な袋から取り出して並べてくれます。これが“u”pLaTeXであるゆえんですね。
 なのでパッケージを使わずにキリル文字を原稿に書いた時も特にエラーになることはなく、代わりにカナと同じく縦向きに組まれます。ここまで前提です。

 そして今やりたいのはフランス語やギリシャ語を横倒しにする、すなわちupLaTeXが出力する時に使う「最低限のアルファベット」の範囲を拡大して、拡張アルファベットもその中に含めることです。
 デフォルトの「最低限のアルファベット」の範囲というのが遠い昔、はるか彼方の銀河系でコンピュータが128文字しか扱えなかったころに作られたOT1フォントエンコーディングになります。16×8しかない表にアルファベットと最小限の記号が詰め込まれています。これで組版システムができちゃうんだから表音文字ってのは気楽なもんだよ┐(´д`)┌
 まあそんな数では早晩破綻します。そのため16×16あるT1エンコーディングと、さらに追加の記号を収めたTS1エンコーディングが作られました。T1にはほとんどのアクセントつきアルファベットが、TS1には§などの記号が収められています。
 これらを使えるようにするための呪文が、最初に書いた\usepackage[T1]{fontenc}\usepackage{textcomp}でした。

 これでめでたくフランス語が書けるようになったかというとさにあらず。出力用の袋は追加されたけれど、まだupLaTeXがそれを認識していません。「アクセントつきアルファベットとかは欧文脳の部分で処理しろ」という命令を通してやる必要があって、これがinputencとpxcjkcatパッケージの機能になります。

 さてやっと準備が整いました。pxnoncjkモードでほとんどを欧文扱いにしてやってタイプセットすると、フランス語スペイン語あたりまではちゃんと欧文扱いで組まれますがギリシャキリル文字はダメです。何故ならT1・TS1の表の中にないから
 広がったとはいえT1エンコーディングもたかが256文字です。主要なアクセントつきアルファベットを収めたらもういっぱいです。欧文として認識はできたものの、出力の段になって肝心の活字がない、という状態こそがこの壁の原因だったようです。やれやれ。

 対策はもちろんあって、活字を用意してやればいいんです。キリル文字を含んでいるフォントエンコーディングT2Aギリシャ文字LGRです。これをT1エンコーディングに追加してやることでupLaTeXは新たな活字を手にしたことになります。

\usepackage[T2A,LGR,T1]{fontenc}  %標準にしたいものを最後に置く

 さあもう文句ないだろうと思ったら最後の試練がありました。upLaTeXは文字種を自動判別してくれませんキリル文字に出会ったらT2Aエンコーディングに切り替える、みたいな動作はしてくれないので、使うべきエンコーディングをその都度人間が指定してやらなければなりません。
 そこで登場するのがBabelパッケージです。本文において\foreignlanguage{russian}{中身}で囲ってやることでようやくT2Aエンコーディングが働き、めでたく日本語の文書に横倒しのヨーロッパ諸語を埋め込むことができました。

 ……ああ疲れた。

(※実は筆者の環境においてfontencでT2A“だけ”を指定すると、Babelを使わないベタ書きでもキリル文字とアクセント文字をどちらもきちんと組むことができました。ただどう動いているのかが分からないので裏技としておきます。鋭意調査中です)

激闘TeX:文字と記号のタテヨコ

 筆者はド素人ですが、ド素人なりにサイトのページには可能な限り分かりやすく、こうすればいいという結論を書くように心がけています。ですがもちろんそこに至るまでにものすごく迷走したり試行錯誤しています。
 失敗の繰り返しなのでサイトやQiitaみたいなところには上げられないし、ということで、自分用の備忘録として、そういうTeXとの死闘の記録や詳しい解説をここに書いていこうと思います。
(環境はすべてupLaTeX、ファイルの文字コードUTF-8です)

 さて アクセントと特殊記号 後編 では「アクセントつきアルファベットや全角扱いになってしまう記号を、“コマンドなしのベタ書きで”欧文扱いの横倒しで組ませる」ということをやりました。
 基本的には記事で書いた通りZRさんのpxcjkcatパッケージを使うんですが、思い通りの挙動にするまでがけっこう長かったです。

 とりあえず「upLaTeX でアクセント付きのラテン文字などがうまく出力されないときの対処法」を参考に一番シンプルな設定にしてみると、下の例ではハートが出てくるところでつまづきました。

\documentclass{utbook}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc}
\usepackage[prefernoncjk]{pxcjkcat}  %これだけ
\begin{document}
cassino de la jetée de Nice
†‡©£§¶«ギュメ»{\copyright}{\pounds}  %一般的な西欧語の文章で使う記号
♡☆♪※●▲■‼  %日本語の小説で使いそうなやつ
Братья Карамазовы  %ロシア語を使いたくなった時のために
Μοιρα  %サンホラーのために
\end{document}

 改めて先ほどの記事の補遺や、「[改訂新版]upLaTeXを使おう」の 欧文のUTF-8入力との併用 などをよく読んでみると、これはprefernoncjkモードが『漢字・かな・ハングル等の明らかな「CJK文字」以外は全て欧文扱いに』してしまうからのようです。
 CJK文字の具体的な範囲はREADMEによると、

  • kanji: 漢字・部首・注音字母: hani, haniA, haniB, haniC, hani1, hani2, cjk01, cjk02, cjk03, cjk05, cjk06, bopo, bopo1.
  • kana: ひらがな・カタカナ: hira, kana, kana1.
  • cjk: CJK 記号の一部・全角/半角互換形・彝文字: cjk04, cjk08, cjk07, cjk09, cjk10, cjk11, cjk12, cjk13, sym15, yiii, yiii1.
  • hangul: ハングル完成形・ハングル字母: hang, hang1, hang2, hangA, hangB.

 本文2行目までは全てASCII及びT1・TS1エンコーディングに含まれるいわゆる“半角”記号なので、inputencを通してLaTeXネイティブ命令に変換される1か、でなければtextcompが適切に取り扱ってくれます。
 ポイントなのが"cjk"ブロックで、3行目からはそこに含まれない(もちろんTS1にもない)ので扱いきれずにエラーを吐くみたいでした。

 解決策は\cjkcategory命令の第1引数に和文扱いしたいブロックを全部書いてやることなんですがうん、ちょっと待って。日本語の小説で使うには分が悪すぎる。
 たとえば用例として挙げられている○や▲や□は「Geometric Shapes」に属するのでIDはsym18になります。
 ところがここにハートはありません。♡や☆や♪は「Miscellaneous Symbols」(sym19)に入ります。
 これら及び必要な記号ブロックをcjk扱いにしてやっても他の文字は全部欧文扱いなので、ダッシュの位置がずれるとか縦向きにしたいまで横向きになるとかそれゆえの問題が残ります。(ダッシュは間が繋がったから位置さえマトモなら是非使いたかったんだけど…)

 あと愕然としたのが†‡ダガー・ダブルダガー)と(パラグラフ)と§(セクション)。¶と§がLatin-1 Supplementに入ってるのでてっきりダガーもだと思ったのに、何故かこいつらだけ「General Punctuation」に入ってる。
 prefernoncjkモードならGeneral~も欧文扱いになってるんだから別にいいかというとそうでもなくて、さらに愕然としたことにもGeneral Punctuationに入っているんですよ。米印が欧文扱いになってちょっと小さめに表示された時は驚いた。てっきり日本の記号だと思ってた。

f:id:isaribisaitoh:20171010203241j:plain
衝撃

 なのでダガーのみを横倒しにして他は和文扱いというようなことはできません。さらに恐ろしいことに×と÷はLatin-1 Supplementに入っていたりするのでこれも分離できません。(「Latin-1 Punctuation and Symbols」というスクリプトがあって本当に約物だけなので、これを使えば算術記号と分けて定義できそうなんだけど多分upLaTeX側で使えない)
 どうすりゃいいんだよ!必要な記号だけ横倒しできないのかよ!

 ……でえーと、私は何をしたかったんだっけ。そうそう、フランス語をきちんと表示したかったんだった。
 正直これだけの用途なら「アルファベット類のみ欧文扱いにして他は全部和文扱い」にした方が早かったです。prefernoncjkモードをやめてprefercjkvarモードを使い、欧文扱いしたいブロックを追加することにします。

\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc}
\usepackage[prefercjkvar]{pxcjkcat}  %アルファベット・ギリシャ・キリル文字のみ欧文扱いに
\cjkcategory{latn1}{noncjk}  %そこにLatin-1 Supplementを加える

 それであとはもう文体に合わせて運用していくしかなさげです。外国語が、出てきてもせいぜい仏・独・西ぐらいという人は上の設定で充分でしょう。
 逆にルーマニア語だのベトナム語だのをガリガリ使いたい人はprefernoncjkで、\cjkcategory{sym18,sym19,<あとsym04とかsym08あたり>}{cjk}をプラスしてやればだいたいなんとかなると思います。

 そしてここまでやってもなお立ちはだかるギリシャ語とキリル文字の壁。長くなったので次回に回します。