Problem with formatting of PHP + HTML

Asked by Pierre Dumuid

I am using emacs 22.2.1, with php-mode 1.4.1a-nxhtml and nXhtml 1.52. When I create a file as follows:
-----------------
<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>Hello</td>
        </tr>
        <?php

for ($i=1;$i<5; $i++) {
  if (1) {
    echo "<tr><td>foobar</td></tr>";
  }
  if (1) {
    if (1) {
      if (1) {
        ?>
        <tr>
          <td>
            <p>the brace below (should have 2 spaces in front of it!</p>
          <td>
        </tr>
        <?php
      }
    }
  }
  $foo = "test".bar;
  for ($i=1;$i<5; $i++) {
    if () {
    }
  }
}
        ?>
      </table>
    </td>
  </tr>
</table>
--------------------------
and what I get when indenting using nxhtml-mumamo mode is:
--------------------------
<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>Hello</td>
        </tr>
<?php

for ($i=1;$i<5; $i++) {
  if (1) {
    echo "<tr><td>foobar</td></tr>";
  }
  if (1) {
    if (1) {
      if (1) {
?>
   <tr>
     <td>
       <p>the brace below (should have 2 spaces in front of it!</p>
     <td>
   </tr>
<?php
}
}
}
$foo = "test".bar;
for ($i=1;$i<5; $i++) {
  if () {
  }
}
}
?>
   </table>
    </td>
  </tr>
</table>
--------------------------
i.e. the depth of indenting is lost from one chuck of PHP to the other and one chunck of HTML to the other. Is this what other people get, or have I configured emacs incorrectly?

Question information

Language:
English Edit question
Status:
Solved
For:
nXhtml Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
lborgman (lennart-borgman) said :
#1

Hi Pierre

Unfortunately that is what other people get too. This indentation problem is a bit hard to solve in a general way. I have to think about it.

Revision history for this message
lborgman (lennart-borgman) said :
#2

Please try version 1.54. I think I have fixed this problem there.

Revision history for this message
Pierre Dumuid (pierre-dumuid) said :
#3

Hi Lennart,
Thanks for getting back so quickly on it. I have tested it once more, (just the above code) and I now get:
-------------------
<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>Hello</td>
        </tr>
<?php
for ($i=1;$i<5; $i++) {
  if (1) {
    echo "<tr><td>foobar</td></tr>";
  }
  if (1) {
    if (1) {
      if (1) {
?>
   <tr>
     <td>
       <p>the brace below (should have 2 spaces in front of it!</p>
     <td>
   </tr>
<?php
                           }
      }
    }
    $foo = "test".bar;
    for ($i=1;$i<5; $i++) {
      if () {
      }
    }
  }
?>
   </table>
    </td>
  </tr>
</table>
-------------------
This has improved, however, there are now 3 tab stops before followed by 3 spaced after the second "<?php". Also, the second HTML chunk isn't continuing the indentation level.

The only other problem with the mode is that it's difficult to select all the text with the mouse.

Revision history for this message
lborgman (lennart-borgman) said :
#4

Could you please try the following:

- Indent <?php at least one space (there is a bug there, unfortunately)
- Add a closing parenthesis to the "(should have 2 ..." sentence
- Add a closing } because there is one missing

Then try indenting again (by selecting all and pressing Tab).

Revision history for this message
Pierre Dumuid (pierre-dumuid) said :
#5

----------------
Latest result is:
---------------
<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>Hello</td>
        </tr>
     <?php
       for ($i=1;$i<5; $i++) {
         if (1) {
           echo "<tr><td>foobar</td></tr>";
         }
         if (1) {
           if (1) {
             if (1) {
        ?>
        <tr>
          <td>
            <p>random text.</p>
          <td>
        </tr>
      <?php
             }
           }
         }
         $foo = "test".bar;
         for ($i=1;$i<5; $i++) {
           if () {
           }
         }
       }
        ?>
     </table>
    </td>
  </tr>
</table>
----------------
I've decided to take out the bracket's altogether.

I found that I could make the second HTML chunk match the indentation of the first HTML chunk by indenting the <?php as you asked for. It appears however that doing so indents the PHP code as well.

There is now two tab's and 1 space after the second <?php.

I have observed that if I manually correct the first lines after all the "<?php" bits of text, the indenting becomes correct as follows:
---------------
<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>Hello</td>
        </tr>
     <?php
for ($i=1;$i<5; $i++) {
  if (1) {
    echo "<tr><td>foobar</td></tr>";
  }
  if (1) {
    if (1) {
      if (1) {
        ?>
        <tr>
          <td>
            <p>random test.</p>
          <td>
        </tr>
        <?php
      }
    }
  }
  $foo = "test".bar;
  for ($i=1;$i<5; $i++) {
    if () {
    }
  }
}
?>
     </table>
    </td>
  </tr>
</table>

Revision history for this message
Pierre Dumuid (pierre-dumuid) said :
#6

"Add a closing } because there is one missing" I couldn't find this one.

Revision history for this message
lborgman (lennart-borgman) said :
#7

You are right, there is no closing } missing (wonder why it was missing for me).

Ok, I am a bit surprised that you wanted the indentation in the last example. I have actively tried to avoid that :-)

I will put in an option for it. Do you know which indentation other people want in a case like this (after the <?php)?

Revision history for this message
Pierre Dumuid (pierre-dumuid) said :
#8

I am unsure of what you are saying that you don't like about the final indenting.

 * <tr>'s should be at the same depth before and after the <?php

<table>
  <tr>
<?php

?>
  </tr>
</table>

 * indentation for an if statement is:

if (1) {
}

so if there is html in there?

if (1) {
?>
<i>hello</i>
<?php
}

Is there something that you dis-agree with? In general, I think that indentation is used to show if one has missed out a } or forgot to close a html tag. Or forgot to add the <tr> before the <td> (i.e. the depth should match!)

Pierre

Revision history for this message
lborgman (lennart-borgman) said :
#9

No, I agree with you but actually doing the indentation is quite complex. There are many situations to care about and I am not sure how the indentation functions that are called actually behave in all situations.

However the input from you have been quite valueable. I will think a bit about it again and come back.

Revision history for this message
lborgman (lennart-borgman) said :
#10

Hi Pierre

I have tried to solve the problem you reported and some other smaller indentation bugs. Can you please try version 1.55 that I just uploaded?

Since there may be different views on how to indent a <?php ... ?> chunk and similar cases I changed the meaning of

  mumamo-submode-indent-offset

You have to set this to nil to make indentation be like you want it.

There is a test case now for the problem you reported. You can run it with

   M-x nxhtmltest-run-indent

Revision history for this message
Pierre Dumuid (pierre-dumuid) said :
#11

Still not quite right. With this example, the first } after the second <?php has 10 spaces before it, rather than 6. Also the final } in the code has 10 spaces before it, and pressing tab and tab at the last "?>" moves the "?>" in and out.

Pierre

<table>
  <tr>
    <td>
      <table>
 <tr>
   <td>Hello</td>
 </tr>
 <?php
for ($i=1;$i<5; $i++) {
  if (1) {
    echo "<tr><td>foobar</td></tr>";
  }
  if (1) {
    if (1) {
      if (1) {
        ?>
 <tr>
   <td>
     <p>random test.</p>
   </td>
 </tr>
 <?php
          }
    }
  }
  $foo = "test".bar;
  for ($i=1;$i<5; $i++) {
    if () {
    }
  }
          }
 ?>
      </table>
    </td>
  </tr>
</table>

Revision history for this message
lborgman (lennart-borgman) said :
#12

Hi Pierre

The first } after <?php is a bug in php-mode. Can you please try to report that to Aaron, the author? Or if you can not get in contact with him try to speak to David House. See the page on Emacs wiki about php-mode.

The last } is indented ok for me. Please give me a recipe to reproduce it.

Revision history for this message
lborgman (lennart-borgman) said :
#13

I have tried to report the problem with the first } after <?php as an Emacs bug. Let us wait and see what happens with that.

Revision history for this message
lborgman (lennart-borgman) said :
#14

I got an answer from Alan Mackenzie that I think solved the problem:

  http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=877

The solution is included in nXhtml version 1.57

Revision history for this message
lborgman (lennart-borgman) said :
#15

This now works in nXhtml (from version 1.57).