Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First pass at #453 (text-based syntaxes should be designed for humans) #472

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

LeaVerou
Copy link
Member

@LeaVerou LeaVerou commented Feb 1, 2024


💥 Error: 405 Method Not Allowed 💥

PR Preview failed to build. (Last tried on Feb 1, 2024, 4:56 PM UTC).

More

PR Preview relies on a number of web services to run. There seems to be an issue with the following one:

🚨 CSS Spec Preprocessor - CSS Spec Preprocessor is the web service used to build Bikeshed specs.

🔗 Related URL

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html lang='en'><head><meta content='text/html; charset=utf-8' http-equiv='Content-Type'><title>CSS Spec Preprocessor</title><link href='/bikeshed/img/favicon.png' rel='icon' type='image/png'><link href='/bikeshed/core/stylesheets/base.css' rel='stylesheet' type='text/css'><link href='/bikeshed/core/stylesheets/system.css' rel='stylesheet' type='text/css'><link href='/bikeshed/stylesheets/bikeshed.css' rel='stylesheet' type='text/css'><script nonce='yX49Hx7TSQ+TYNhkin+44vBek9P1c1gPbhHXWEAwNL0=' type='text/javascript'><!--
var gCookieDomain=".api.csswg.org";var gCookiePath="\/bikeshed\/";var gCookiePrefix="bikeshed_";var gUserId=false;if(!Array.indexOf){Array.prototype.indexOf=function(obj){for(var index=0;index<this.length;index++){if(this[index]==obj){return index;}}return-1;}}try{if(1!=Node.ELEMENT_NODE){throw true;}}catch(exc){var Node={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3};}var system={mAPIXHR:null,mAPITimer:null,mAPIQueue:[],commonPrefix:function(string1,string2){var prefix='';var length=((string1.length<string2.length)?string1.length:string2.length);var index=-1;while((++index<length)&(string1[index]==string2[index])){prefix+=string1[index];}return prefix;},getCookie:function(name){var cookies=document.cookie.split(';');name+='=';var prefixedName=gCookiePrefix+name;for(var index=0;index<cookies.length;index++){cookie=cookies[index].trim();if(prefixedName==cookie.substring(0,prefixedName.length)){return unescape(cookie.substring(prefixedName.length));}if(name==cookie.substring(0,name.length)){return unescape(cookie.substring(name.length));}}return null;},setCookie:function(name,value){if(null==value){var expDate=new Date();expDate.setDate(expDate.getDate()-1);document.cookie=gCookiePrefix+name+'=; expires='+expDate.toGMTString()+'; '+'domain='+gCookieDomain+'; path='+gCookiePath;}else{document.cookie=gCookiePrefix+name+'='+escape(value)+'; expires=0; '+'domain='+gCookieDomain+'; path='+gCookiePath;}},hasClass:function(element,className){if(element&&('className'in element)){var classes=element.className.split(' ');if(-1<classes.indexOf(className)){return true;}}return false;},addClass:function(element,className){if(element){var classes=(('className'in element)?element.className.split(' '):new Array());if(-1==classes.indexOf(className)){classes.push(className);element.className=classes.join(' ');}}},removeClass:function(element,className){if(element){var classes=(('className'in element)?element.className.split(' '):new Array());var index;while(-1<(index=classes.indexOf(className))){classes.splice(index,1);}element.className=classes.join(' ');}},findChildWithClass:function(element,className){if(element){var children=element.children;if(children){for(var index=0;index<children.length;index++){var child=children[index];if((child.nodeType==Node.ELEMENT_NODE)&&this.hasClass(child,className)){return child;}}}}return null;},getFirstElementChild:function(element){if(element){var children=element.children;for(var index=0;index<children.length;index++){var child=children[index];if(child.nodeType==Node.ELEMENT_NODE){return child;}}}return null;},iterateElementChildren:function(element,callback){if(element){var children=Array();for(var index=0;index<element.children.length;index++){var child=element.children[index];if(child.nodeType==Node.ELEMENT_NODE){children.push(child);}}for(var index=0;index<children.length;index++){var child=children[index];var result=callback(child,index);if(result){return result;}}}return false;},isLoggedIn:function(){var login=document.getElementById('login');return(login&&this.hasClass(login,'loggedin'));},toggleLoginMenu:function(){var login=document.getElementById('login');if(login){if(this.hasClass(login,'open')){this.removeClass(login,'open');}else{this.addClass(login,'open');}}},updatePageURI:function(uri){var login=document.getElementById('login');if(login){var a=system.createElement('a',{'href':uri});uri=a.pathname;system.iterateElementChildren(login,function(div,index){system.iterateElementChildren(div,function(item,index){if(item.hasAttribute('href')){var href=item.getAttribute('href');var index=href.indexOf('/return/');if(0<=index){var prefix=system.commonPrefix(uri,item.pathname);item.setAttribute('href',href.substring(0,index)+'/return/'+uri.substring(prefix.length));}}});});}},createProgressIcon:function(){var progress=this.createElement('span',{'class':'progress p1'});progress.setAttribute('data-timer',setInterval(function(){var state=progress.className.slice(-1);state=(state-0+1)%8;progress.className='progress p'+state;},125));return progress;},removeProgressIcon:function(progress){if(progress){clearInterval(progress.getAttribute('data-timer')-0);if(progress.parentNode){progress.parentNode.removeChild(progress);}}},addLoadEvent:function(onLoad){try{var oldOnLoad=window.onload;if('function'!=typeof(window.onload)){window.onload=onLoad;}else{window.onload=function(){if(oldOnLoad){oldOnLoad();}onLoad();}}}catch(err){}},createElement:function(tagName,attrs,textContent){var element=document.createElement(tagName);if(attrs){for(attr in attrs){if(attrs.hasOwnProperty(attr)){if('id'==attr){element.id=attrs.id;}else if('className'==attr){element.className=attrs.className;}else if(attrs[attr]){element.setAttribute(attr,attrs[attr]);}}}}if(textContent){element.textContent=textContent;}return element;},emptyElement:function(element){if(element){while(element.lastChild){element.removeChild(element.lastChild);}}},addFormData:function(form,name,value){if(form){var hidden=this.createElement('input',{'type':'hidden','name':name,'value':value});form.appendChild(hidden);}},addUserHyperLink:function(parent,user){var userName=(user&&user.name ?((user.name.toLowerCase()==user.full_name.toLowerCase())?user.full_name:user.name):'Anonymous User');var title=(user&&user.full_name&&user.name&&(user.full_name.toLowerCase()!=user.name.toLowerCase())?user.full_name:'');var email=(user&&user.email&&user.display_email ?user.email:'');var uri=(user&&user.uri ?user.uri:'');if(email){parent.appendChild(this.createElement('a',{'href':'mailto:'+email,'title':title},userName));}else if(uri){parent.appendChild(this.createElement('a',{'href':uri,'title':title},userName));}else{parent.appendChild(this.createElement('span',{'title':title},userName));}},_processAPIQueue:function(){var call=this.mAPIQueue.shift();if(call){if(!this.mAPIXHR){this.mAPIXHR=new XMLHttpRequest();}this.mAPIXHR.onreadystatechange=function(){if(4==system.mAPIXHR.readyState){if(call.callback){var response=false;try{if('json'==call.type){response=JSON.parse(system.mAPIXHR.responseText);}else if('xml'==call.type){response=system.mAPIXHR.responseXML.documentElement}}catch(err){}try{call.callback(system.mAPIXHR.status,response);}catch(err){if(call.progress){system.removeProgressIcon(call.progress);}throw err;}}if(call.progress){system.removeProgressIcon(call.progress);}this.mAPITimer=setTimeout(function(){system._processAPIQueue()},10);}};try{this.mAPIXHR.open(call.method,call.uri,true);if(call.callback){this.mAPIXHR.setRequestHeader('Accept','application/json');}if('POST'==call.method){this.mAPIXHR.setRequestHeader('Content-type','application/x-www-form-urlencoded');this.mAPIXHR.setRequestHeader('Content-length',call.data.length);}if('xml'==call.type){this.mAPIXHR.responseType='document';}else{this.mAPIXHR.responseType='';}this.mAPIXHR.send(call.data);}catch(err){if(call.progress){system.removeProgressIcon(call.progress);}this.mAPITimer=setTimeout(function(){system._processAPIQueue()},10);throw err;}}else{this.mAPITimer=null;}},callAPI:function(method,uri,data,type,callback,progressTarget,priority){var progress=null;if(progressTarget){progress=this.createProgressIcon();progressTarget.parentNode.insertBefore(progress,progressTarget.nextSibling);}var call={method:method,uri:uri,type:type,data:data,callback:callback,progress:progress};if(priority){this.mAPIQueue.unshift(call);}else{this.mAPIQueue.push(call);}if(null===this.mAPITimer){this.mAPITimer=setTimeout(function(){system._processAPIQueue()},10);}},encodeParams:function(params,arrayName){var paramString='';for(param in params){if(params.hasOwnProperty(param)){if(paramString){paramString+='&';}var name=param;if(arrayName){name=arrayName+'['+param+']';}if(Array.isArray(params[param])){for(var index=0;index<params[param].length;index++){paramString+=name+'[]='+params[param][index];}}else if('object'==typeof(params[param])){paramString+=this.encodeParams(params[param],param);}else if('boolean'==typeof(params[param])){paramString+=name+'='+(params[param]+0);}else{paramString+=name+'='+encodeURIComponent(params[param]);}}}return paramString;},getXML:function(uri,params,callback,progressTarget,priority){if(null==params){params={};}var paramString=this.encodeParams(params);this.callAPI('GET',uri+'?'+paramString,null,'xml',callback,progressTarget,priority);},callAPIGet:function(uri,params,callback,progressTarget,priority){if(null==params){params={};}var loginKey=this.getCookie('loginkey');if(loginKey){params.loginkey=loginKey;}var paramString=this.encodeParams(params);this.callAPI('GET',uri+'?'+paramString,null,'json',callback,progressTarget,priority);},callAPIPost:function(uri,params,callback,progressTarget,priority){if(null==params){params={};}var loginKey=this.getCookie('loginkey');if(loginKey){params.loginkey=loginKey;}var data=this.encodeParams(params);this.callAPI('POST',uri,data,'json',callback,progressTarget,priority);},abortAPICall:function(){if(this.mAPIXHR){if((4!=this.mAPIXHR.readyState)&&(0!=this.mAPIXHR.readyState)){this.mAPIXHR.abort();}}},setMenuAlert:function(menuId,state){var menuLink=document.getElementById(menuId);if(menuLink){if(state){if(!this.hasClass(menuLink,'alert')){var icon=this.createElement('span',{'class':'icon alert','style':'top: -14px ! important'});menuLink.appendChild(icon);this.addClass(menuLink,'alert');setTimeout(function(){icon.setAttribute('style','top: '+(menuLink.offsetTop+3)+'px');},100);}}else{if(this.hasClass(menuLink,'alert')){var icon=menuLink.lastChild;icon.setAttribute('style','top: -14px ! important');this.removeClass(menuLink,'alert');setTimeout(function(){menuLink.removeChild(icon);},500);}}}}};
// --></script><script nonce='yX49Hx7TSQ+TYNhkin+44vBek9P1c1gPbhHXWEAwNL0=' type='text/javascript'><!--
function updateForceControl(){var outputHTMLControl=document.getElementById('output-error');var forceControl=document.getElementById('force');var dieOnControl=document.getElementById('die-on');forceControl.disabled=outputHTMLControl.checked;dieOnControl.disabled=(outputHTMLControl.checked||forceControl.checked);}system.addLoadEvent(updateForceControl)
// --></script></head><body><div class='header'><div class='logo'><a href='http://www.w3.org/' rel='home'><img alt='W3C' src='/bikeshed/core/img/logo-w3c-screen-sm.png'></a></div><div class='login' id='login'><div><a href='/bikeshed/login/return/'>Login</a></div></div><p class='nav'><a>Home</a></p><h1 id='title'>CSS Spec Preprocessor</h1></div><div class='body'><p class='error'>Must use POST to process URL</p><form accept-charset='utf-8' action='' enctype='multipart/form-data' method='post'><fieldset><legend>Specification Source</legend><table class='labels'><tr><th><label for='file'>Upload File:</label></th><td><input name='file' type='file' value=''></td></tr><tr><th><label for='url'>Load from URL:</label></th><td><input id='url' name='url' size='60' type='text' value='https://raw.githubusercontent.com/w3ctag/design-principles/8d2f183e4495fd8f5ad6b6479199e1cc96f93c1e/index.bs'></td></tr><tr><th><label for='text'>Enter Text:</label></th><td><textarea cols='80' id='text' name='text' rows='10'></textarea></td></tr></table></fieldset><fieldset><legend>Options</legend><table class='labels'><tr><th><label for='input'>Input Type:</label></th><td><select id='input' name='input'><option selected value='spec'>Specification</option><option value='issues'>Issues List</option></select></td></tr><tr><th>Output:</th><td><input id='output-error' name='output' type='radio' value='err'><label for='output-error'>Errors &amp; Warnings</label><br><input id='output-html' name='output' type='radio' value='html'><label for='output-html'>Generated HTML</label><br><input checked id='output-frame' name='output' type='radio' value='frame'><label for='output-frame'>Both (in Frames)</label></td></tr><tr><th style='vertical-align: baseline'>Error Handling:</th><td><input checked id='force' name='force' type='checkbox' value='1'><label for='force'>Force HTML Output (ignore fatal errors)</label></td></tr><tr><th>Die On:</th><td><select id='die-on' name='die-on'><option selected value='nothing'>Nothing</option><option value='fatal'>Fatal</option><option value='link-error'>Link Error</option><option value='warning'>Warning</option><option value='everything'>Everything</option></select></td></tr><tr><th><label for='time'>Default Time:</label></th><td><input id='time' name='time' size='40' type='text'> (yyyy-mm-dd hh:mm:ss +0000)</td></tr></table></fieldset><input name='action' type='submit' value='Process'></form><div class='instructions'>This tool may also be used from the command line, e.g.:<code><span>curl http://api.csswg.org/bikeshed/ -F [email protected] -F force=1 &gt; Overview.html</span><span>curl http://api.csswg.org/bikeshed/ -F url=https://drafts.csswg.org/css-align-3/Overview.bs &gt; Overview.html</span><span>curl http://api.csswg.org/bikeshed/ -F [email protected] -F output=err</span><span>curl http://api.csswg.org/bikeshed/ -F [email protected] -F input=issues &gt; Issues.html</span></code><p>Valid paramaters are:</p><dl><dt>file</dt><dd>file contents to process</dd><dt>url</dt><dd>url contents to process</dd><dt>input</dt><dd>input type: &#039;spec&#039; or &#039;issues&#039; (default = &#039;spec&#039;)</dd><dt>output</dt><dd>desired output: &#039;html&#039;, &#039;err&#039; (default to Accept: header value)</dd><dt>force</dt><dd>send HTML output even if fatal errors encountered, otherwise output determined by Accept: header</dd><dt>die-on</dt><dd>select category of error to stop on, options are: nothing, fatal, link-error, warning, everything (default = &#039;fatal&#039;)</dd><dt>time</dt><dd>default specification time (yyyy-mm-dd hh:mm:ss +0000)</dd><dt>md-&lt;key&gt;</dt><dd>override metadata (e.g.: md-status=CR)</dd></dl><p>Parameters may be submitted as query arguments or form fields. HTTP POST must be used.</p><p>Further information can be found in the <a href='https://speced.github.io/bikeshed/#curl'>Bikeshed documentation</a>.</p></div></div><div class='footer'><address>Please send comments, questions, and error reports to <a href='&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#105;&#107;&#101;&#115;&#104;&#101;&#100;&#64;&#99;&#115;&#115;&#119;&#103;&#46;&#111;&#114;&#103;?subject=CSS Spec Preprocessor'>the server administrator &#60;&#98;&#105;&#107;&#101;&#115;&#104;&#101;&#100;&#64;&#99;&#115;&#115;&#119;&#103;&#46;&#111;&#114;&#103;&#62;</a></address></div><script nonce='yX49Hx7TSQ+TYNhkin+44vBek9P1c1gPbhHXWEAwNL0=' type='text/javascript'><!--
document.getElementById('output-error').onchange=function(event){updateForceControl()};document.getElementById('output-html').onchange=function(event){updateForceControl()};document.getElementById('output-frame').onchange=function(event){updateForceControl()};document.getElementById('force').onchange=function(event){updateForceControl()};
// --></script></body></html>

If you don't have enough information above to solve the error by yourself (or to understand to which web service the error is related to, if any), please file an issue.

Ideally, the syntax would be optimized for human usability, and tooling would optimize the syntax for efficiency.
However, this is not always possible.
In these cases, explore if it is possible to provide syntax that is flexible enough to accommodate both use cases.
The downside of this approach is that it increases the complexity of the language, and humans may still need to read the less human-friendly syntax.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this sentence is getting at. What less-friendly syntax are you talking about?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's talking about cases where you need two have two syntaxes, one optimized for efficiency and one for humans.

@torgo torgo added this to the 2024-03-04-week milestone Mar 3, 2024
The downside of this approach is that it increases the complexity of the language, and humans may still need to read the less human-friendly syntax.
Lastly, if efficiency is truly critical, consider whether a binary format may be more appropriate.

<div class="example">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plinss and @LeaVerou also gave JSON as a great example (+1 to both of these from me):

  • Not allowing trailing commas is not good for humans.
  • Not allowing comments is really not good for humans.

Therefore, optimizing it for human usability also makes it easier to develop tools to generate it.

Human usability may often be at odds with parsing performance and filesize efficiency.
Ideally, the syntax would be optimized for human usability, and tooling would optimize the syntax for efficiency.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a little unclear as to what this line was trying to say; @LeaVerou explained it's about situations e.g. where you can minify a file with tooling to make it more efficient - that was good clarification I think, so I suggest including that in the text.

It feels like there could be quite big implications here (accepting tooling as integral to the process, if we've not already explicitly done so elsewhere). Solving for both human readability and efficiency is an important challenge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New principle: Text-based syntaxes should be designed to be usable by humans
4 participants