Skip to content

\csname

yex.keyword.Csname(parser) #

Creates new control tokens.

\csname must be followed by a series of tokens of any of the basic categories. Expandable controls will be expanded; unexpandable controls aren't allowed. The series must end with \endcsname.

This series will become the name of a new control token, which will initially point at \relax. See p40 of the TeΧbook for more details.

You can use this to create control tokens with weird names-- even the empty string. Note that if you create a token with a name beginning with an underscore, that underscore will be doubled in doc[name] so that it doesn't conflict with yex's internal settings.

Source code in yex/keyword/other.py
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
@yex.decorator.control()
def Csname(parser):
    r"""
    Creates new control tokens.

    \csname must be followed by a series of tokens of any of the basic
    categories. Expandable controls will be expanded; unexpandable controls
    aren't allowed. The series must end with \endcsname.

    This series will become the name of a new control token, which will
    initially point at \relax. See p40 of the TeXbook for more details.

    You can use this to create control tokens with weird names-- even
    the empty string. Note that if you create a token with a name
    beginning with an underscore, that underscore will
    be doubled in doc[name] so that it doesn't conflict with yex's internal
    settings.
    """

    logger.debug(r'\csname: reading name of new control')

    location = parser.location

    name = ''
    try:
        while True:
            item = parser.next(level='executing', on_eof='raise')

            if isinstance(item, yex.parse.Token) and item.is_from_tex:
                name += item.ch
            else:
                raise yex.exception.CsnameWeirdFollowingError(
                        problem = item,
                        )
    except yex.exception.EndcsnameError:
        pass

    if name.startswith('_'):
        name = f'_{name}'

    logger.debug(r'\csname: new control will be called %s', name)

    result = yex.parse.ControlName(
            ch = name,
            location = location,
            )

    logger.debug(r'\csname: new control is %s', result)

    name_with_backslash = '\\'+name
    if name_with_backslash not in parser.doc.controls:
        parser.doc.controls[name_with_backslash] = Relax()
        logger.debug(r'\csname: added to controls table')

    return result