[release-branch.go1.3] go.tools/present: allow intentionally empty parameters

««« CL 105070043 / 1e6e75afb0cd
go.tools/present: allow intentionally empty parameters

Fixes golang/go#7613.

LGTM=r
R=adg, r
CC=golang-codereviews
https://golang.org/cl/105070043

»»»

LGTM=dsymonds
R=dsymonds
CC=golang-codereviews
https://golang.org/cl/148300043
diff --git a/present/code.go b/present/code.go
index 2816a87..a176435 100644
--- a/present/code.go
+++ b/present/code.go
@@ -238,6 +238,8 @@
 			res[i] = v
 		case '$':
 			res[i] = "$"
+		case '_':
+			// Do nothing; '_' indicates an intentionally empty parameter.
 		default:
 			return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
 		}
diff --git a/present/doc.go b/present/doc.go
index afd50e7..da71e8d 100644
--- a/present/doc.go
+++ b/present/doc.go
@@ -168,10 +168,14 @@
 The syntax is simple: 1 or 3 space-separated arguments.
 The first argument is always the file name.
 If there are more arguments, they are the height and width;
-both must be present.
+both must be present, or substituted with an underscore.
+Replacing a dimension argument with the underscore parameter
+preserves the aspect ratio of the image when scaling.
 
 	.image images/betsy.jpg 100 200
 
+	.image images/janet.jpg _ 300
+
 iframe:
 
 The function "iframe" injects iframes (pages inside pages).
diff --git a/present/image.go b/present/image.go
index 2bab429..cfa2af9 100644
--- a/present/image.go
+++ b/present/image.go
@@ -32,6 +32,11 @@
 	case 0:
 		// no size parameters
 	case 2:
+		// If a parameter is empty (underscore) or invalid
+		// leave the field set to zero. The "image" action
+		// template will then omit that img tag attribute and
+		// the browser will calculate the value to preserve
+		// the aspect ratio.
 		if v, ok := a[0].(int); ok {
 			img.Height = v
 		}