2

I've noticed a glitch in the syntax highlighting of C# code on Stack Overflow. The tag's standard highlighting doesn't include the keywords using and namespace

However, when adding the language directive <!-- language: lang-csharp -->, those are highlighted. So I request to add this directive to every post in tag.

Here's the rendering screenshot.

Enter image description here

10
  • Link to an example? The syntax highlighting works fine for me every time. Commented Jul 22, 2013 at 4:10
  • 6
    lang-csharp does not exist. You're seeing the default syntax highlighting by using that. The c# tag is set to use lang-cs.
    – animuson StaffMod
    Commented Jul 22, 2013 at 4:10
  • See this stackoverflow.com/questions/6297279/nested-namespaces - The keyword namespace isn't highlighted. Commented Jul 22, 2013 at 4:17
  • @animuson lang-cs doesn't work for some keywords. But the lang-csharp works. Commented Jul 22, 2013 at 4:17
  • @CodyGray Added example Commented Jul 22, 2013 at 4:24
  • @SriHarshaChilakapati - Have a look at this answer for more details. lang-cs or lang-c# (tag name) can be used.
    – Himanshu
    Commented Jul 22, 2013 at 4:26
  • 5
    @Sri: Like I said, lang-csharp does not exist. By using that it's reverting to default. If those keywords happen to get highlighted, that's merely coincidence.
    – animuson StaffMod
    Commented Jul 22, 2013 at 4:28
  • @animuson I've added the rendering screenshot. Since this is working, could you change that to lang-csharp? Commented Jul 22, 2013 at 4:37
  • @Sri: I can't change it to an identifier that doesn't exist. We're kindof limited to the list of identifiers available... I really don't know how else to make you understand that lang-csharp is not real.
    – animuson StaffMod
    Commented Jul 22, 2013 at 4:39
  • @animuson Sorry. I'm just saying that this is working. Even the Google's page on it says to use lang-cs. Maybe I'll file a issue on their site. Commented Jul 22, 2013 at 4:42

2 Answers 2

3

If the identifier you use in the language directive

  • starts with lang-
  • but is not listed under "Language codes" in this post

you would get the default syntax highlighting behavior.

Specifically, invalid identifiers such as lang-csharp, lang-doesnotexist, and lang-iambanana are treated as lang-default.

The default syntax highlighting (lang-default) works by highlighting any keyword from any predefined keyword list in prettify.js. This means it can "grab" keywords from multiple languages, even though the code is written in a single language.

== End of TL;DR region ==

Some examples to illustrate what I'm saying

Example 1: lang-cs

This markdown

<!-- language: lang-cs -->

    public static bool IsAwesome { get { return true; } }

renders as

syntax highlighting with lang-cs

Example 2: lang-i-am-a-banana

This markdown

<!-- language: lang-i-am-a-banana -->

    public static bool IsAwesome { get { return true; } }

renders as

syntax highlighting with lang-i-am-a-banana

The difference between lang-cs and lang-i-am-a-banana

If we compare Examples 1 and 2, note that bool and get which was not highlighted with lang-cs was highlighted with lang-i-am-a-banana.

Looking at the C#'s keyword list

var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
      "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
      "new,operator,private,protected,public,this,throw,true,try,typeof"];
var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
      "abstract,as,base,bool,by,byte,checked,decimal,delegate,descending," +
      "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
      "internal,into,is,let,lock,null,object,out,override,orderby,params," +
      "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
      "unchecked,unsafe,ushort,var,virtual,where"];
  • I'm not sure why bool was not highlighted with lang-cs, maybe SO/SE is not using the most recent revision of prettify.js? The latest revision at the time of writing, r303 added bool to C#'s keyword list.
  • get is most definitely not in C#'s keyword list, even in the latest revision

Assuming that SO/SE is using an older revision, in lang-i-am-a-banana mode, bool is "grabbed" from C++'s keyword list

var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
      "dynamic_cast,explicit,export,friend,generic,late_check," +
      "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
      "static_cast,template,typeid,typename,using,virtual,where"];

in lang-i-am-a-banana mode, get is "grabbed" from JavaScript's keyword list

var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
      "debugger,eval,export,function,get,null,set,undefined,var,with," +
      "Infinity,NaN"];

Invalid identifiers that don't start with lang-

The fallback to lang-default isn't triggered if your identifier doesn't start with lang-

<!-- language: i-am-a-banana -->

    public static bool IsAwesome { get { return true; } }

renders as

syntax-highlighting with i-am-a-banana

or renders according to language tag the question is using. In this case, the language directive simply gets silently ignored.

7

Like animuson said, the correct identifier for the C# language is lang-cs. Alternatively, you could use the name of the tag, in which case it would be c#. This is all documented here, which gives the identifiers for each language.

What you're using (lang-csharp) is no different than lang-apples-and-bananas or lang-invalid-language. Because there is no lang-csharp identifier, you're just getting the default syntax highlighting, used when no (valid) language is specified.

So the real problem here is that namespace is not highlighted as a keyword when the C# syntax highlighting is applied. We've had this problem before with the virtual keyword, and the get and set keywords, and the new C# 5.0 keywords.

The same answer applies to this as it did to all of those previous cases: Stack Exchange outsources syntax highlighting to Google Prettify, so if there's a bug in the implementation, it's their bug.

Looking at the code, the problem is fairly obvious. In the current revision of prettify.js, where the keywords are defined for various supported languages, namespace is missing from the C# list:

  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
      "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
      "static,struct,switch,typedef,union,unsigned,void,volatile"];
  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
      "new,operator,private,protected,public,this,throw,true,try,typeof"];
  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
      "concept,concept_map,const_cast,constexpr,decltype," +
      "dynamic_cast,explicit,export,friend,inline,late_check," +
      "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
      "template,typeid,typename,using,virtual,where"];
  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
      "abstract,boolean,byte,extends,final,finally,implements,import," +
      "instanceof,null,native,package,strictfp,super,synchronized,throws," +
      "transient"];
  var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
      "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
      "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock," +
      "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," +
      "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var," +
      "virtual,where"];

The only language that has a namespace keyword is C++, and the C++ keywords are not imported to the list of C# keywords. The fix is therefore quite simple, it just needs to be brought to the attention of someone with commit rights to the source code.

5
  • I'll file an issue on it. Thanks for clarification. Commented Jul 22, 2013 at 5:42
  • 1
    @CodyGray The equivalent to <!-- language: lang-cs --> is <!-- language: c# -->. <-- language: lang-c# -->, mentioned in your post, would trigger the default behavior much like <!-- language: lang-csharp --> would. Commented Jul 22, 2013 at 7:01
  • @doubleDown Don't miss the "edit" link ;-) Sometimes my fingers get carried away. Commented Jul 22, 2013 at 7:02
  • It's interesting that C# keywords contain the Java keywords. Because some of them (like "transient", "package", "strictfp", "super", etc...) are certainly not C# keywords... Commented Jul 22, 2013 at 8:06
  • 1
    Indeed, it looks like more of them are not C# keywords than are. Keyword-based highlighting seems intuitively wrong to me anyway, but I guess it's by far the easiest way of doing it. Just raises the maintenance costs substantially. Commented Jul 22, 2013 at 8:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .