ruricolist / spinneret

Common Lisp HTML5 generator
MIT License
368 stars 26 forks source link

Spinneret sometimes adds white space in an <a>, and sometimes doesn't, causing inconsistent display #37

Open dfmorrison opened 4 years ago

dfmorrison commented 4 years ago

Consider, for example,

(defun f (url)
  (with-html
    (:h4 (:raw "&nbsp;") (:a :href url "Some Text"))))

If I call it as

(f "http://short.com/")

I get

<h4>&nbsp;<a href="http://short.com/">Some Text</a></h4>

But if I call it as

(f "http://thisisreallyreallylonglonglonglongonwegoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com/")

I get

<h4>&nbsp;<a
href="http://thisisreallyreallylonglonglonglongonwegoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com/">
  Some Text</a></h4>

Note the addition of white space, a new line and a couple of spaces, between the <a ..> and the actual text.

These display differently, even though the inputs to the spinneret code differ only in the links’ URLs which shouldn’t affect the display at all, I wouldn’t think.

ruricolist commented 4 years ago

The wrapping is deliberate. When pretty printing attributes are wrapped according to serapeum:*fill-column*.

How do they display differently?

dfmorrison commented 4 years ago

Assuming default presentation of links, the unwrapped one displays as “Some text”, underlined. The wrapped one displays shifted over to the right by the width of a space, and is preceded by an underlined blank space. I’ve confirmed this both in Chrome and in Firefox.

BTW, this is a simplified example reduced down from a real world one in the web site I’m (re-)building, where this problem causes what should be all left aligned navigation links in a narrow, left hand pane to not line up properly.

Note that the problem is not wrapping at attributes, which I don't think would cause any trouble. Rather it's wrapping between the '>' and the actual text. That is, it's (sometimes, but not always, depending upon length) Spinneret is sticking whitespace into a place where it is meaningful, but where there is no necessarily already existing whitespace to collapse with it.

ruricolist commented 4 years ago

I will look into fixing this as soon as I have the chance, but in the meantime have you considered disabling pretty printing of HTML?

On Sat, Feb 22, 2020, 6:09 PM Don Morrison notifications@github.com wrote:

Assuming default presentation of links, the unwrapped one displays as “Some text”, underlined. The wrapped one displays shifted over to the right by the width of a space, and is preceded by an underlined blank space. I’ve confirmed this both in Chrome and in Firefox.

BTW, this is a simplified example reduced down from a real world one in the web site I’m (re-)building, where this problem causes what should be all left aligned navigation links in a narrow, left hand pane to not line up properly.

Note that the problem is not wrapping at attributes, which I don't think would cause any trouble. Rather it's wrapping between the '>' and the actual text. That is, it's (sometimes, but not always, depending upon length) sticking whitespace into a place where it is meaningful, but where there is no necessarily already whitespace to collapse to it.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ruricolist/spinneret/issues/37?email_source=notifications&email_token=AAC7AKHD4JG52W3ZXHKKLFDREG5FNA5CNFSM4KZUETD2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEMVNZKI#issuecomment-590011561, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAC7AKAB55N2EE4OED7CNLTREG5FNANCNFSM4KZUETDQ .

dfmorrison commented 4 years ago

Oh, I'm sure I can work around the issue. I was just waiting to hear back from you before I gave it any thought. But if it's going to be a while until it's fixed, or you believe it isn't something that needs fixing, I can easily find some way to get things as I need them, I'm sure.

Thanks!

BTW, I really do like Spinneret. A lot tidier and more convenient than the various templating things I've had to use in other languages.

dfmorrison commented 4 years ago

Sorry, I accidentally closed this, now reopened.

Ambrevar commented 3 years ago

I just got bitten by this as well.

Any of the following fixes it for me:

Is this expected? Which option is recommended for reliable outputs?

Shouldn't Spinneret default to produce reliable outputs and only have the human / pretty-printing feature as an option?

iamFIREcracker commented 2 years ago

Bumped into this too, today, and for me the solution was a combination of tweaking both SPINNERET:*SUPPRESS-INSERTED-SPACES* and SPINNERET:*FILL-COLUMN*.

Setting SPINNERET:*SUPPRESS-INSERTED-SPACES* to T enables proper rendering of punctuation after links (and inline elements in general):

(let ((spinneret:*fill-column* 50))
  (spinneret:with-html-string
    (:span "Click the " (:a :href "https://google.com" ) ".")))
=>
"<span>Click the <a href=https://google.com></a> .</span>"

(let ((spinneret:*fill-column* 50)
      (spinneret:*suppress-inserted-spaces* t))
  (spinneret:with-html-string
    (:span "Click the " (:a :href "https://google.com" ) ".")))
=>
"<span>Click the <a href=https://google.com></a>.</span>"

Setting SPINNERET:*FILL-COLUMN* to a very high value instead, make sure any punctuation following a very long and unbreakable token (i.e. a URL) is not pushed to a new line (causing an extra space to be rendered):

(let ((spinneret:*fill-column* 50))
  (spinneret:with-html-string
    (:span "Click the " (:a :href "https://www.google.com" ) ".")))
=>
"<span>Click the <a href=https://www.google.com></a> 
 .</span>"

(let ((spinneret:*fill-column* 50)
      (spinneret:*suppress-inserted-spaces* t))
  (spinneret:with-html-string
    (:span "Click the " (:a :href "https://www.google.com" ) ".")))
=>
"<span>Click the <a href=https://www.google.com></a>
 .</span>"

(let ((spinneret:*fill-column* 100)
      (spinneret:*suppress-inserted-spaces* t))
  (spinneret:with-html-string
    (:span "Click the " (:a :href "https://www.google.com" ) ".")))
=>
"<span>Click the <a href=https://www.google.com></a>.</span>"

I guess if this was an acceptable solution, then maybe there should be a better way to disable line-wrapping, e.g. setting SNIPPERET:*FILL-COLUMN* to -1.

Thoughts?!

Sod-Almighty commented 11 months ago

No movement in three years. Is this project dead?

ruricolist commented 11 months ago

No movement in three years. Is this project dead?

Wouldn't the best way to determine that be to look at the closed issues, rather than the open ones?

q3cpma commented 2 weeks ago

My workaround is to run find dst -type f -name '*.html' -exec sed -z -E -i 's#</a>\n *#</a>#g' {} + afterwards (GNU sed only).

I disabled all formatting instead:

(let ((spinneret:*suppress-inserted-spaces* t)
     (spinneret:*html-style* :tree)
     (*print-pretty* nil))
  ...)
ruricolist commented 2 weeks ago

I've pushed up a branch to address the extra whitespace (fix-inline-whitespace) if anyone would be interested in testing it.

q3cpma commented 6 days ago

Sorry for the delay, a bit busy. Tested it with only (spinneret:*suppress-inserted-spaces* t) and a few *fill-column* values and it seems to be working well here, no more spurious spaces after <a/>

Sadly, I'm still forced to disable pretty printing because (spinneret:*html-style* :tree) (I strongly disagree with that stupid HTML5 decision of splitting with XML just to save a few <p/>) inserts significant spaces too.