\indent and \noindent: details from Knuth's The TeXbook

Both statements are correct but perhaps nether tell the full truth.

In hmode, \indent adds a box of width \parindent so looks like a horizontal space, \noindent adds an empty hlist, which, as your first quote says, has no effect.

In vmode then both commands cause a new paragraph to start and a new hlist, beginning with an indentation box in the case of \indent.


When TeX is in vertical mode, \noindent starts horizontal mode. When TeX is already in horizontal mode, \noindent has no effect. There's no contradiction.


The relevant sections from the TeX program:

During program startup (INITEX), §1088 defines the primitive \noindent as command code start_par with extra param of 0: noindent defined

Later in the main control loop (the part where TeX reacts to every token that reaches its “stomach”) if this start_par command is seen,

  1. If the current mode is vertical mode, then TeX calls new_graf with false: vmode + start_par This new_graf does what you expect, in terms of starting a new paragraph: new_graf This is what your quoted sentence says too:

    This is exactly like \indent except that TeX starts out in horizontal mode with an empty list instead of with an indentation.

  2. Else (horizontal mode or math mode), TeX calls indent_in_hmode: hmode/mmode + start_par This indent_in_hmode as you can see does absolutely nothing at all when cur_chr = 0 (i.e. \noindent instead of \indent): indent_in_hmode This is what your quoted sentence says too:

    \noindent has no effect in horizontal mode.


Edit: The corresponding LuaTeX code (in C), for comparison:

  • tex/commands.c:

    primitive_tex("noindent", start_par_cmd, 0, 0);
    
  • tex/maincontrol.c:

    static void run_start_par_vmode (void) {
        new_graf((cur_chr > 0));
    }
    
    static void run_start_par (void) {
       if (cur_chr != 2)
           indent_in_hmode();
    }
    

    and (leaving out new_graf as it's a bit long)

    void indent_in_hmode(void)
    {
        halfword p;
        if (cur_chr > 0) {
            /*tex \.{\\indent} */
            p = new_null_box();
            width(p) = par_indent_par;
            if (abs(mode) == hmode)
                space_factor_par = 1000;
            else
                p = new_sub_box(p);
            tail_append(p);
        }
    }
    

    and (in init_main_control):

        jump_table[vmode + start_par_cmd] = run_start_par_vmode;
        jump_table[hmode + start_par_cmd] = run_start_par;
        jump_table[mmode + start_par_cmd] = run_start_par;
    

At the top of page 283, Knuth is describing what happens when TeX is in vertical mode and it finds \noindent: this command starts horizontal mode appending nothing to the horizontal list.

At the bottom of page 282 the effect of \indent is described: it starts horizontal mode appending an empty box as wide as \parindent (the width can also be negative).

These two descriptions are in Chapter 24, “Summary of Vertical Mode”.

On page 286 the effect of \noindent when TeX is in horizontal mode is described: the effect is doing nothing at all. This is in Chapter 25, “Summary of Horizontal Mode”.

Similarly, the effect of \noindent in math mode is described: nothing at all again (page 291). This is in Chapter 26, “Summary of Math Mode”.