Parser für Smallcaps

Redefinition von Makros, Definition eigener Befehle sowie neuer Umgebungen


keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Die eine Aussage muss ich korrigieren.
Er setzt aus irgendeinem Grund immer ein 'Ä' vor den Umlaut. Auch bei 'ö' und 'ü'.


MoeWe
Forum-Century
Forum-Century
Beiträge: 247
Registriert: Fr 30. Aug 2019, 15:35
Kontaktdaten:

Re: Parser für Smallcaps

Beitrag von MoeWe »

Ich bin mir relativ sicher, dass das Problem wirklich beim RegExp zu finden ist. Es scheint, dass gerade [] und das Ersetzen mit Umlauten Probleme machen (also in pdfLaTeX; LuaLaTeX und XeLaTeX haben keine Probleme).

Code: Alles auswählen

\documentclass[ngerman]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{expl3,xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\testA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { ([Ö]) } { \cB\{\c{color}\cB\{blue\cE\} \1 \cE\} } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }

\NewDocumentCommand{\testGutA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { (Ö) } { \cB\{\c{color}\cB\{blue\cE\} \1 \cE\} } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }
\ExplSyntaxOff



\begin{document}
\testA{otto atta}

\testGutA{otto atta}

\testA{OTTO ATTA}

\testGutA{OTTO ATTA}

\testA{öttö ättä}

\testGutA{öttö ättä}

\testA{ÖTTÖ ÄTTÄ}

\testGutA{ÖTTÖ ÄTTÄ}
\end{document}

oder

Code: Alles auswählen

\documentclass[ngerman]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{expl3,xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\testA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { ([Ö]) } { 1 } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }

\NewDocumentCommand{\testGutA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { (Ö) } { 2 } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }
\ExplSyntaxOff



\begin{document}
\testA{otto atta}

\testGutA{otto atta}

\testA{OTTO ATTA}

\testGutA{OTTO ATTA}

\testA{öttö ättä}

\testGutA{öttö ättä}

\testA{ÖTTÖ ÄTTÄ}

\testGutA{ÖTTÖ ÄTTÄ}
\end{document}

oder

Code: Alles auswählen

\documentclass[ngerman]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{expl3,xparse}
\usepackage{xcolor}

\ExplSyntaxOn
\NewDocumentCommand{\testA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { O } { Ö } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }

\NewDocumentCommand{\testGutA}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { O } { \c{"}O } \l_keth_text_tl
    \l_keth_text_tl
    \ (\meaning \l_keth_text_tl)
  }
\ExplSyntaxOff



\begin{document}
\testA{otto atta}

\testGutA{otto atta}

\testA{OTTO ATTA}

\testGutA{OTTO ATTA}

\testA{öttö ättä}

\testGutA{öttö ättä}

\testA{ÖTTÖ ÄTTÄ}

\testGutA{ÖTTÖ ÄTTÄ}
\end{document}

\text_uppercase:n hingegen hat - soweit ich weiß - keine Probleme mit Umlauten (zumindest die Zeichen aus T1 sollten auch in pdfLaTeX gehen).

Code: Alles auswählen

\documentclass[ngerman]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{expl3,xparse}

\ExplSyntaxOn
\NewDocumentCommand{\testB}{m}
  {
    \text_uppercase:n {#1}
  }
\ExplSyntaxOff

\begin{document}
\testB{otto atta}

\testB{OTTO ATTA}

\testB{öttö ättä}

\testB{ÖTTÖ ÄTTÄ}
\end{document}

keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Also, so funktioniert es:

Code: Alles auswählen

\documentclass[ngerman]{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{expl3,xparse}
\usepackage{relsize}
\usepackage{hyperref}

\ExplSyntaxOn
\tl_new:N \l_keth_text_tl

\cs_generate_variant:Nn \text_uppercase:n {o}

\NewDocumentCommand{\textfakesc}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { ([A-ZÄÖÜ]+) } { \cB\{\c{larger}\[1\] \1 \cE\} } \l_keth_text_tl
    \regex_replace_all:nnN { [ð] } {  } \l_keth_text_tl
    \regex_replace_all:nnN { [Ä] } { \c{"}A } \l_keth_text_tl
    \regex_replace_all:nnN { [Ö] } { \c{"}O } \l_keth_text_tl
    \regex_replace_all:nnN { [Ü] } { \c{"}U } \l_keth_text_tl
    \regex_replace_all:nnN { [ä] } { \c{"}A } \l_keth_text_tl
    \regex_replace_all:nnN { [ö] } { \c{"}O } \l_keth_text_tl
    \regex_replace_all:nnN { [ü] } { \c{"}U } \l_keth_text_tl
    \regex_replace_all:nnN { [ß] } { SS } \l_keth_text_tl
    \text_uppercase:o \l_keth_text_tl
  }

\NewExpandableDocumentCommand{\textfakescwithpdfstring}{m}
  {
    \texorpdfstring
      {
        \textfakesc { #1 }
      }
      {
        \text_uppercase:n { #1 }
      }
  }
\ExplSyntaxOff

\begin{document}
\tableofcontents
\part{\textfakescwithpdfstring{Über öde Späße}}
\end{document}

(Auch wenn mir nicht ganz klar ist, warum bei einem Ersetzen der Umlaute immer der Ersatzwert der dritten Zeile mit ausgegeben wird... [Weshalb ich dort eingebaut habe, dass der Buchstabe "Eth" durch "nichts" ersetzt werden soll.])

Allerdings gibt es leider noch ein anderes Problem mit dieser Lösung, welches aber hoffentlich deutlich einfacher zu beseitigen ist:
Wenn ich hyperref mit den Voreinstellungen verwende, funktioniert alles wunderbar. Da ich jedoch z.T. griechische Buchstaben als Gliederungsnummern verwenden muss und diese über \textalpha usw. implementiert habe, muss ich hyperref mit der Option "unicode=true" verwenden, damit die griechischen Buchstaben alle in den bookmarks angezeigt werden. Wenn diese Option aktiviert ist, werden jedoch alle Umlaute des durch \text_uppercase manipulierten Textes durch ein "A" mit Tilde ersetzt:

Code: Alles auswählen

\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[artemisia]{textgreek}
\usepackage{expl3,xparse}
\usepackage{relsize}
\usepackage{hyperref}
\hypersetup{
    unicode=true,
    bookmarksnumbered=true
}

\ExplSyntaxOn
\tl_new:N \l_keth_text_tl

\cs_generate_variant:Nn \text_uppercase:n {o}

\NewDocumentCommand{\textfakesc}{m}
  {
    \tl_set:Nn \l_keth_text_tl {#1}
    \regex_replace_all:nnN { ([A-ZÄÖÜ]+) } { \cB\{\c{larger}\[1\] \1 \cE\} } \l_keth_text_tl
    \regex_replace_all:nnN { [ð] } {  } \l_keth_text_tl
    \regex_replace_all:nnN { [Ä] } { \c{"}A } \l_keth_text_tl
    \regex_replace_all:nnN { [Ö] } { \c{"}O } \l_keth_text_tl
    \regex_replace_all:nnN { [Ü] } { \c{"}U } \l_keth_text_tl
    \regex_replace_all:nnN { [ä] } { \c{"}A } \l_keth_text_tl
    \regex_replace_all:nnN { [ö] } { \c{"}O } \l_keth_text_tl
    \regex_replace_all:nnN { [ü] } { \c{"}U } \l_keth_text_tl
    \regex_replace_all:nnN { [ß] } { SS } \l_keth_text_tl
    \text_uppercase:o \l_keth_text_tl
  }

\NewExpandableDocumentCommand{\textfakescwithpdfstring}{m}
  {
    \texorpdfstring
      {
        \textfakesc { #1 }
      }
      {
        \text_uppercase:n { #1 }
      }
  }
\ExplSyntaxOff

\newcommand*{\greek}[1]{%
    \ifcase \value{#1}%
        \arabic{#1}%
    \or%
        \textalpha%
    \or%
        \textbeta%
    \or%
        \textgamma%
    \or%
        \textdelta%
    \else%
        \arabic{#1}%
    \fi%
}

\renewcommand*{\thechapter}{\greek{chapter}}

\begin{document}
\tableofcontents
\part{\textfakescwithpdfstring{Über öde Späße}}
\chapter{Erstes Kapitel}
\end{document}

Wenn Du da noch mal drauf schauen könntest... - das wäre super!


keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Mir fällt gerade auf, der Code lässt sich auch mit drei Zeilen weniger schreiben, indem man

Code: Alles auswählen

\regex_replace_all:nnN { [Ää] } { \c{"}A } \l_keth_text_tl

usw. verwendet.


keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Mit dieser Lösung funktioniert alles:

Code: Alles auswählen

\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{expl3,xparse}
\usepackage{relsize}
\usepackage{hyperref}
\hypersetup{
    unicode=true,
    bookmarksnumbered=true
}

\ExplSyntaxOn
\tl_new:N \l_keth_text_tl

\cs_generate_variant:Nn \text_uppercase:n {o}

\NewDocumentCommand{\textfakesc}{m}
    {
        \tl_set:Nn \l_keth_text_tl {#1}
        \regex_replace_all:nnN { ([A-ZÄÖÜ]+) } { \cB\{\c{larger}\[1\] \1 \cE\} } \l_keth_text_tl
        \regex_replace_all:nnN { [ð] } {  } \l_keth_text_tl
        \regex_replace_all:nnN { [Ää] } { \c{"}A } \l_keth_text_tl
        \regex_replace_all:nnN { [Öö] } { \c{"}O } \l_keth_text_tl
        \regex_replace_all:nnN { [Üü] } { \c{"}U } \l_keth_text_tl
        \regex_replace_all:nnN { [ß] } { SS } \l_keth_text_tl
        \text_uppercase:o \l_keth_text_tl
    }

\newcommand\textupper{}

\pdfstringdefDisableCommands
    {
        \cs_set:Npn\textupper #1{ \use:e {\text_uppercase:n {#1}} }
    }

\NewExpandableDocumentCommand{\textfakescwithpdfstring}{m}
    {
        \texorpdfstring
        {
            \textfakesc { #1 }
        }
        {
            \textupper { #1 }
        }
    }
\ExplSyntaxOff

\begin{document}
\tableofcontents
\part{\textfakescwithpdfstring{Über öde Späße}}
\end{document}

Nochmals danke für die Hilfe!
Es wäre dennoch gut, wenn ich wüsste, warum der Hack mit "Eth" notwendig ist bzw. wie das Teil jetzt eigentlich genau funktioniert. Anderenfalls hätte ich ein wenig ein ungutes Gefühl bei der Nutzung des Parsers.


gast

Re: Parser für Smallcaps

Beitrag von gast »

keth-tex hat geschrieben:
Sa 6. Jun 2020, 12:19

Ich möchte bestimmte Überschriften, welche im Stil

Code: Alles auswählen

\bfseries\sffamily

formatiert sind, als Smallcaps setzen. Eine solche Kombination ist für die gewünschte Schriftart nicht verfügbar.

Ist der Font als OpenType-Font verfügbar? Eventuell funktioniert es dann, wenn man XeLaTeX und fontspec und das passende Letter-Feature verwendet. Bei OpenType sind SmallCaps auch oft direkt im Hauptfont (bzw. hier im Bold-Font) enthalten. In PDFLaTeX sind sie dann je nach Fonteinbindung nicht verfügbar, mit XeLaTeX aber schon.

Ich bin selbst kein fontspec-Experte und war daher schon so manches Mal überrascht, was damit alles geht.


MoeWe
Forum-Century
Forum-Century
Beiträge: 247
Registriert: Fr 30. Aug 2019, 15:35
Kontaktdaten:

Re: Parser für Smallcaps

Beitrag von MoeWe »

Soweit ich sehen kann, ist diese Gymnastik mit dem ð notwendig, da l3regex zumindest mit pdfLaTeX Unicode nicht vollständig unterstützt. Ich hatte oben ja bereits Beispiele gezeigt. Insbesondere scheint es problematisch zu sein, nicht-ASCII-Zeichen in [] zu verwenden (warum, kann ich Dir nicht genau sagen, aber mein Tipp ist, dass es damit zusammenhängt, dass nicht-ASCII-Zeichen aus mehreren Bytes bestehen, die bei der Darstellung in [] einzeln zerlegt werden und dann auch einzeln gematcht werden, das führt dann unter Umständen dazu, dass ein Buchstabe Byte-per-Byte verarbeitet wird und dabei kaputtgeht; bei normalem Matching ohne [] passiert das meist nicht, da der Buchstabe dort auch als Bytesequenz behandelt werden kann). Du nutzt aber [] sehr intensiv. Vielleicht kommst Du ja mit weniger aus.

Code: Alles auswählen

\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{expl3,xparse}
\usepackage{relsize}
\usepackage{hyperref}
\hypersetup{
    unicode=true,
    bookmarksnumbered=true
}

\ExplSyntaxOn
\tl_new:N \l_keth_text_tl

\cs_generate_variant:Nn \text_uppercase:n {o}

\NewDocumentCommand{\textfakesc}{m}
    {
        \tl_set:Nn \l_keth_text_tl {#1}
        \regex_replace_all:nnN { ([A-Z]+) } { \cB\{\c{larger}\[1\] \1 \cE\} } \l_keth_text_tl
        \regex_replace_all:nnN { Ä } { \cB\{\c{larger}\[1\] \c{"}A \cE\} } \l_keth_text_tl
        \regex_replace_all:nnN { Ö } { \cB\{\c{larger}\[1\] \c{"}O \cE\} } \l_keth_text_tl
        \regex_replace_all:nnN { Ü } { \cB\{\c{larger}\[1\] \c{"}U \cE\} } \l_keth_text_tl
        \text_uppercase:o \l_keth_text_tl
    }

\newcommand\textupper{}

\pdfstringdefDisableCommands
    {
        \cs_set:Npn\textupper #1{ \use:e {\text_uppercase:n {#1}} }
    }

\NewExpandableDocumentCommand{\textfakescwithpdfstring}{m}
    {
        \texorpdfstring
        {
            \textfakesc { #1 }
        }
        {
            \textupper { #1 }
        }
    }
\ExplSyntaxOff

\begin{document}
\tableofcontents
\part{\textfakescwithpdfstring{Über öðe Späße}}
\textfakescwithpdfstring{Über öðe Späße}
\end{document}

keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Ich bin jetzt etwas irritiert... Wenn ich es richtig sehe, funktioniert der von Dir gepostete Code einwandfrei (und ohne Hack), was jedoch aus Deinem Text gar nicht wirklich hervorgeht, wo eigentlich nur Probleme und Lösungsansätze beschrieben werden.
Aber vielleicht ist das ja nur Ausdruck Deiner Bescheidenheit oder Deines Humors.
Insofern es jetzt nicht doch noch irgendein Problem mit dieser Lösung gibt, welches ich übersehe, ..sage ich tausend Dank!!


MoeWe
Forum-Century
Forum-Century
Beiträge: 247
Registriert: Fr 30. Aug 2019, 15:35
Kontaktdaten:

Re: Parser für Smallcaps

Beitrag von MoeWe »

Naja, ich hab eine Theorie erklärt, warum ich glaube, dass die vorherigen Versuche mit [] Probleme hatten. Dann hab ich eine Lösung gezeigt, die ohne [] auskommt. Das scheint zumindest in meinen Tests zu funktionieren. Allerdings kann ich keinesfalls garantieren, dass die Lösung auch für denn Produktiveinstatz nutzbar ist.

Alles, was ich bis jetzt gesehen habe, suggeriert, dass l3regex mit pdfLaTeX nur ASCII-Zeichen vollständig unterstützt. Nicht-ASCII-Zeichen scheinen in einigen Fällen (mehr aus Zufall und nicht von der Spezifikation her) zu funktionieren. Das Problem ist nur, dass ich nicht sagen kann, wo genau die Grenzen liegen. Im ToDo-Block der expl3-Dokumentation interface3 findet sich nur der Punkt "UTF-8 mode for pdfTeX", was sich zumindest für mich so anhört, als sei UTF-8 zur Zeit in pdfLaTeX nicht offiziell (vollständig) unterstützt.

Von daher: Nutz den Code ruhig, wenn er in Deinen Tests das richtige tut, aber überprüfe die Ausgabe sorgfältig.


keth-tex

Re: Parser für Smallcaps

Beitrag von keth-tex »

Alles klar. Dann weiß ich Bescheid.
(Ich hatte tatsächlich einige Tests durchgeführt und konnte keine Probleme feststellen. Von daher bin ich recht optimistisch...)


Antworten