www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Macro text preprocessor

reply "Walter" <newshound digitalmars.com> writes:
With all this talk about generating HTML files with boilerplate, I use a
simple macro text preprocessor to do it. Here it is, and btw it shows what
can be done with just a few lines of D!
---------------------------------
// Copyright (C) 2005 by Digital Mars www.digitalmars.com
// All Rights Reserved
// Written by Walter Bright

import std.file;
import std.stdio;
import std.c.stdlib;
import std.string;
import std.ctype;
import std.date;

void usage()
{
    printf(
"Macro process file.\n"
"Use:\n"
"    macro infile outfile args...\n"
"    args are of the form name=value\n"
"    $(name) in text is replaced with value\n"
 );
}

int main(char[][] cmdargs)
{
    int i;
    char[] arg;
    char[][] args;
    char[] fin = null;
    char[] fout = null;
    int errors;

    writefln("macro 1.01");

    if (cmdargs.length < 3)
    { usage();
 return EXIT_FAILURE;
    }

    errors = 0;
    args.length = cmdargs.length - 3;
    args.length = 0;
    for (i = 1; i < cmdargs.length; i++)
    { arg = cmdargs[i];
 if (i <= 2)
 {
     if (arg[0] == '-')
     {
  writefln("unrecognized switch '%s'", arg);
  errors++;
     }
     else if (i == 1)
  fin = arg;
     else
  fout = arg;
 }
 else
     args ~= arg;
    }
    if (errors)
 return EXIT_FAILURE;

    predefinedMacros();

    foreach (char[] arg; args)
 macroInsert(arg);

    char[] input = cast(char[])std.file.read(fin);
    char[] output;

    output = process(input);

    std.file.write(fout, output);

    return EXIT_SUCCESS;
}

char[] [char[]] mactab;

void macroInsert(char[] arg)
{
    int i = find(arg, '=');
    if (i == -1)
 throw new Error("expected name=value, not " ~ arg);
    char[] name = strip(arg[0 .. i]);
    char[] value = stripl(arg[i + 1 .. length]);
    mactab[name] = value;
}

void predefinedMacros()
{   d_time t = getUTCtime();

    char[] value = toDateString(t);
    mactab["__DATE__"] = value;

    value = format(cast(long)YearFromTime(t));
    mactab["__YEAR__"] = value;
}

char[] process(char[] input)
{
    char[][] lines;
    char[] output;

    lines = splitlines(input);

    // Do backsplash line splicing
    for (int i = 0; i + 1 < lines.length; )
    {
 char[] line = lines[i];

 if (line.length && line[length - 1] == '\\')
 {
     line.length = line.length - 1; // chop off backslash
     line ~= '\n';
     line ~= lines[i + 1];
     lines[i] = line;
     for (int j = i + 1; j + 1 < lines.length; j++)
  lines[j] = lines[j + 1];
     lines.length = lines.length - 1;
     //writefln("line = '%s'", line);
 }
 else
     i++;
    }

    // Macro process lines
    char[] result;
    foreach (char[] line; lines)
    {
 result.length = 0;

 for (int i = 0; i < line.length; )
 {   int j;

     j = find(line[i .. length], '$');
     if (j == -1)
     {
  result ~= line[i .. length];
  break;
     }
     j += i;
     result ~= line[i .. j];
     if (j + 1 == line.length)
     {
  result ~= '$';
  break;
     }
     if (line[j + 1] == '$')
     {
  result ~= '$';
  i = j + 2;
  continue;
     }
     if (isalpha(line[j + 1]))
     {
  result ~= mactab[ line[j + 1 .. j + 2] ];
  i = j + 2;
  continue;
     }
     if (line[j + 1] == '(' && j + 2 != line.length)
     {
  int k = find(line[j + 2 .. length], ')');
  if (k != -1)
  {
      k += j + 2;
      result ~= mactab[ line[j + 2 .. k] ];
      i = k + 1;
      continue;
  }
     }
     result ~= '$';
     i = j + 1;
 }

 if (result.length && result[0] == '.')
 {
     if (result.length >= 4 && result[1 .. 4] == "set")
     {
  macroInsert(result[4 .. length]);
  continue;
     }
     else if (result.length >= 8 && result[1 .. 8] == "include")
     { char[] filename = strip(result[8 .. length]);
  char[] input = cast(char[])std.file.read(filename);
  output ~= process(input);
  continue;
     }
     else
  throw new Error("unknown dot command: " ~ result);
 }
 else
 {
     output ~= result;
     output ~= '\n';
 }
    }

    return output;
}
Aug 23 2005
parent reply "Walter" <newshound digitalmars.com> writes:
Here's an example of how I use it, this is std_random.txt, the eventual html
is at www.digitalmars.com/d/phobos/std_random.html

The header, footer, and sidebar are all boilerplate from macros.inc.

---------------------------------------------------------------------------
.set TITLE=Digital Mars - The D Programming Language - std.random
.set WIKI=Phobos/StdRandom
.include macros.inc

$(HEADER)
$(PHOBOS_S)

<h1 align=center>std.random</h1>


<dl><dl>

 <dt>void <b>rand_seed</b>(uint seed, uint index)
 <dd>The random number generator is seeded at program
 startup with a random value. This ensures that each program
 generates a different sequence of random numbers.
 To generate a repeatable sequence, use <b>rand_seed</b>() to
 start the sequence. <i>seed</i> and <i>index</i> start it, and each
 successive value increments <i>index</i>. This means that the
 <i>n</i>th random number of the sequence can be directly generated
 by passing <i>index + n</i> to <b>rand_seed</b>().
 <p>

 <dt>uint <b>rand</b>()
 <dd>Get next random number in sequence.
 <p>

</dl></dl>


$(PHOBOS_E)
$(FOOTER)
Aug 23 2005
next sibling parent reply "ElfQT" <dethjunk yahoo.com> writes:
In "no frames" conversation I already written about XML commenting.
Let me do it again. Why not store the same information in the same place: 
the code file?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcoriXMLDocumentation.asp

Your example would look like:

/// <summary>
/// The random number generator is seeded at program startup with a random 
value.
/// This ensures that each program generates a different sequence of random 
numbers. /// To generate a repeatable sequence, use <see 
cref="rand_seed()"/> to start the sequence.
/// The parameters start it, and each successive value increments index. 
This means that the nth random number of the sequence can be directly 
generated by passing index + n to <see cref="rand_seed()"/>.
/// </summary>
/// <param name="seed">the random number seed</param>
/// <param name="index">each successive value increments index</param>
/// <returns>void<returns>
void rand_seed(uint seed, uint index)
{
     seed = s;
     index = i;
}

/// <summary>
/// Get next random number in sequence.
/// </summary>
/// <returns>next random number<returns>
uint rand()
{
   ...code...
}

And simle tools should work with this information after, fully 
cross/hyperlinked.
Also, you don't need to write return and parameter types, it's already in 
the code.
Also, compiler should check if the doc (xml comment) is outdated.

If you have a problem with this, as it's sooo Microsoft-ish, well...
Do something similar/equivalent... (But why reinvent the wheel?)

If you are disturbed with comment in code... well first, unittest also 
appears to be there, and second, code editor should collapse the comment 
blocks.
(Also, I'd like to ask if unittests _have_ to be in the same file than the 
tested code?)

Regards,
 ElfQT
Aug 23 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"ElfQT" <dethjunk yahoo.com> wrote in message
news:deg1tc$26sq$1 digitaldaemon.com...
 If you have a problem with this, as it's sooo Microsoft-ish, well...
 Do something similar/equivalent... (But why reinvent the wheel?)

While it's a good idea, I find it just aesthetically ugly in the program source code.
 (Also, I'd like to ask if unittests _have_ to be in the same file than the
 tested code?)

Nope.
Aug 23 2005
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Walter wrote:
 "ElfQT" <dethjunk yahoo.com> wrote in message
 news:deg1tc$26sq$1 digitaldaemon.com...
 
If you have a problem with this, as it's sooo Microsoft-ish, well...
Do something similar/equivalent... (But why reinvent the wheel?)

While it's a good idea, I find it just aesthetically ugly in the program source code.

I agree, it's truly ugly. How about something cleaner, like Javadoc?
Aug 23 2005
parent "Walter" <newshound digitalmars.com> writes:
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message
news:deg8gq$2n93$1 digitaldaemon.com...
 I agree, it's truly ugly.
 How about something cleaner, like Javadoc?

Better, but still ugly. I should probably design a proper one <g>, but I just haven't given it much thought.
Aug 23 2005
prev sibling next sibling parent reply AJG <AJG nospam.com> writes:
Hi,

Walter wrote:
 "ElfQT" <dethjunk yahoo.com> wrote in message
 news:deg1tc$26sq$1 digitaldaemon.com...
 
If you have a problem with this, as it's sooo Microsoft-ish, well...
Do something similar/equivalent... (But why reinvent the wheel?)

While it's a good idea, I find it just aesthetically ugly in the program source code.

I agree. It's ugly, _and_ verbose. XML + triple slashes + indenting is just not a good combination. I think general-user documentation should be kept separate from the actual code. Comments in the code should be there primarily to help the people that create/maintain the module, not general programmers.
(Also, I'd like to ask if unittests _have_ to be in the same file than the
tested code?)

Nope.

What about creating a default unittest file per module? A sort of code-behind variant so that all that test code can be by itself. For instance: Foo.d : Actual module code. Foo.ut.d : Unittest for Foo. I believe this would work because modules already can't contain periods. Also, if a .ut.d file doesn't exist, then it would be simply ignored. Cheers, --AJG.
Aug 23 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 23 Aug 2005 19:51:02 -0400, AJG wrote:

 Hi,
 
 Walter wrote:
 "ElfQT" <dethjunk yahoo.com> wrote in message
 news:deg1tc$26sq$1 digitaldaemon.com...
 
If you have a problem with this, as it's sooo Microsoft-ish, well...
Do something similar/equivalent... (But why reinvent the wheel?)

While it's a good idea, I find it just aesthetically ugly in the program source code.

I agree. It's ugly, _and_ verbose. XML + triple slashes + indenting is just not a good combination.

~~~~ Shudder ~~~~
 I think general-user documentation should be kept separate from the 
 actual code. Comments in the code should be there primarily to help the 
 people that create/maintain the module, not general programmers.

I place documentation inside the source for my projects purely from a practical aspect. As I'm the one person doing both the coding and the documentation, it is more efficient for me to keep them together. Basically if they were in different files they would soon get out of synchronization. However, if I had the luxury of a separate person doing the docs, they would be separated. That's why I've developed a documentation mark up language and a tool to extract it years ago and still use it. The Build utility's HTML docs are generated from the mark up stuff embedded in the source code. -- Derek (skype: derek.j.parnell) Melbourne, Australia 24/08/2005 10:03:37 AM
Aug 23 2005
prev sibling parent Don Clugston <dac nospam.com.au> writes:
AJG wrote:
 Hi,
 
 Walter wrote:
 
 "ElfQT" <dethjunk yahoo.com> wrote in message
 news:deg1tc$26sq$1 digitaldaemon.com...

 If you have a problem with this, as it's sooo Microsoft-ish, well...
 Do something similar/equivalent... (But why reinvent the wheel?)

While it's a good idea, I find it just aesthetically ugly in the program source code.

I agree. It's ugly, _and_ verbose. XML + triple slashes + indenting is just not a good combination.

I think that ideally, it would be Python-esque. IE, whitespace in docs would be syntactically significant. eg, a D-style comment might be /*D functionName Author: ABC Date:xyz Copyright:2005 param1 meaning of this parameter param2 it identifies a parameter by the whitespace at start of the line. If when finished parsing the comment, the list of parameters doesn't match the params in the comment, it's an error if #params in comment >0. (so explaining params is optional, but if you explain one, you must explain all, and mustn't explain any that aren't there). param3 this is another parameter One-line summary Long explanation, which travels over several lines. */ The idea being that if you begin a comment with the special D-comment identifier, you must format it in a particular good style. Some existing well-commented code should automatically be readable. I don't see why you need any kind of <param> tokens, human beings seem to be able to parse (well-formed) comments perfectly well without them.
Aug 23 2005
prev sibling parent reply "ElfQT" <dethjunk yahoo.com> writes:
 While it's a good idea, I find it just aesthetically ugly in the program
 source code.

Well, then put it in a "comment behind" file. (Or change it to your liking. While it's hard form me to accept "aesthetically ugly" in contradiction with usabilty, I can also point that even phobos has different comments, with "//" on variables and some general comments with "/* */".) I can't emphasize enough how excellent a something-like-XML-comment would be. Why? Based on your sample on random, I've made it in C#. Let me show you the usability of that in pictures (It is said that one picture is hundred times better than a word, in my case at least hundred and eighty ;) ). The simple sample base in the code editor (Visual Studio): http://elfqt.simeis.hu/szallit/DComm/Dcomm1.jpg The code used: http://elfqt.simeis.hu/szallit/DComm/CommentTemp.cs Finding it ugly? Hide it: http://elfqt.simeis.hu/szallit/DComm/Dcomm1b.jpg When you type (well, select with intellisense) a method (which, of course should be any class, funct, enum etc.), you get the "help" right there (Don't have to browse, search another doc somewhere else.) http://elfqt.simeis.hu/szallit/DComm/Dcomm2.jpg Using my own code, or Phobos library, or everybody else's lib/code, right there at the use I can get at least a min-help, not to mention that see the signatures of calls and returns and all. http://elfqt.simeis.hu/szallit/DComm/Dcomm3.jpg Every variable can have it's own comment, and it will also show at the place of use: http://elfqt.simeis.hu/szallit/DComm/Dcomm4.jpg If you have any number of overloads on a method, sometimes it's hard to find and match with the right one, well not with xml comment and a good editor. You can go up and down in the list of overloaded calls (and you can easily check on the parameters of each): http://elfqt.simeis.hu/szallit/DComm/Dcomm5.jpg You can use (semi)standard doc generating tools: Just from the little one code file NDoc generates this help: http://elfqt.simeis.hu/szallit/DComm/Dcomm6.jpg http://elfqt.simeis.hu/szallit/DComm/Dcomm6b.jpg (I've uploaded the generated chm too:http://elfqt.simeis.hu/szallit/DComm/Documentation.chm) And well, what is the output, when the compiler gathers the XMl comment? Another xml file: http://elfqt.simeis.hu/szallit/DComm/CommentTemp.xml Why is that interesting? Because if you use something in compiled form, but it has a corresponding definition, tools can use it really well: "Object browser" can show the same info like the above: http://elfqt.simeis.hu/szallit/DComm/Dcomm7.jpg Also, I am not an expert of that, just a "user" - there is more in the commenting system syntax and usage (all in all, you _can_ write comments then generate help with the content and detail like msdn library). OK, D is "just a compiler". But Phobos is a library. A compiler and a library is almost a platform. For a new language (platform, library), well let me say, in the spread of a new language, one important aspect is the learning curve, which mostly emerge with it's standard library. If you want programmers to learn to use libraries as fast as they can, give them a method like this: let them access the info on needed classes, methods, parameters rigth where they use it. If you not formalize comments, then you cannot ensure that the code and the docs will be the same. (Well, considering that C# compiler gives warning (of yourse, everyone should use 'treat warning ass error') if comment is missing or differs.) The goal should be no less than to include the full doc generation in the build process (yes, that's how I do it now). In my personal opinion, when I have to browse the phobos code and the published phobos doc just to find function names and parameters (many times with find in files - until there is not a working editor capable of 'go to definition' function, which in terms of usability is also in connection with formalized commenting) is frustrating on contrast of the ways I tried to describe in this message. I hope you (Walter, and also all the contributors, whom I really respect for what's already accomplished), not find my opinion (and _not_ demand) pushy. There is so much things concerning D that I can't contribute in lack of understanding and experience in compiler technology and low level programming and library design, but if there is something in what I have solid view then the above was one of it. ElfQT (you can reach me at elfqt p1 simeis p2 hu - where p1 is at, p2 is dot)
Aug 25 2005
parent reply "Walter" <newshound digitalmars.com> writes:
I agree completely with you on the usefulness of automatic documentation
generation from the source (after all, it fits right in with the idea of
embedded contracts and unit tests). I just find the C# approach used to be
overcomplicated and ugly in its source form. For example, instead of:

    /// <summary> starting seed </summary>
    private static uint seed;

Wouldn't it be more natural as:

    private static uint seed;    /// starting seed

? And:

/// <summary>
		/// The random number generator is seeded at program startup with a random
value.
		/// This ensures that each program generates a different sequence of
random  numbers.
		/// To generate a repeatable sequence, use <see cref="rand_seed(uint,
uint)"/> to start the sequence.
		/// The parameters start it, and each successive value increments index.
This means that the nth random number of the sequence can be directly
generated by passing index + n to <see cref="rand_seed(uint, uint)"/>.
		/// </summary>
/// <param name="s">the random number seed</param>
		/// <param name="i">each successive value increments index</param>
		/// <returns>void</returns>
		public static void rand_seed(uint s, uint i)
		{
			seed = s;
			index = i;
		}

The compiler knows that the return value is void. Why should the programmer
have to type it in twice? It's going to be something you have to force
programmers to do, rather than it coming naturally. Why should the
programmer have to identify the parameters twice? This could work:

/// The random number generator is seeded at program startup with a random
value.
/// This ensures that each program generates a different sequence of random
numbers.
/// To generate a repeatable sequence, use <see cref="rand_seed(uint,
uint)"/> to start the sequence.
/// The parameters start it, and each successive value increments index.
This means that the nth random
/// number of the sequence can be directly generated by passing index + n to
rand_seed(uint, uint)
public static void rand_seed(
        uint s,    /// the random number seed
        uint i)    /// each successive value increments index
{
seed = s;
index = i;
}

The idea is to make the compiler do the work rather than the programmer. So
while I agree completely with you on the advantages of doing this, I only
disagree with the form that C# and Javadoc take, as they are needlessly and
excessively klunky.

It wouldn't be too hard to adjust dmd to extract and output this info.
Aug 25 2005
next sibling parent Chris Sauls <ibisbasenji gmail.com> writes:
Walter wrote:
 public static void rand_seed(
         uint s,    /// the random number seed
         uint i)    /// each successive value increments index
 {
 seed = s;
 index = i;
 }

Just thought I'd mention this is pretty close to my current coding style anyhow, so I'm all set and in support of it. *g* Except mine tend to look more like: # public static void rand_seed ( # in uint s , // the random number seed # in uint i // each successive value increments index # ) # in { # // some rules for the seed... # } # body { # seed = s ; # index = i ; # } So if this standard convention were adopted... all I'd have to do is triplize a few slashes? That'd be nifty. -- Chris Sauls
Aug 25 2005
prev sibling next sibling parent AJG <AJG_member pathlink.com> writes:
In article <dekveh$2a28$1 digitaldaemon.com>, Walter says...
I agree completely with you on the usefulness of automatic documentation
generation from the source (after all, it fits right in with the idea of
embedded contracts and unit tests). I just find the C# approach used to be
overcomplicated and ugly in its source form. For example, instead of:

    /// <summary> starting seed </summary>
    private static uint seed;

Wouldn't it be more natural as:

    private static uint seed;    /// starting seed

? And:

/// <summary>
		/// The random number generator is seeded at program startup with a random
value.
		/// This ensures that each program generates a different sequence of
random  numbers.
		/// To generate a repeatable sequence, use <see cref="rand_seed(uint,
uint)"/> to start the sequence.
		/// The parameters start it, and each successive value increments index.
This means that the nth random number of the sequence can be directly
generated by passing index + n to <see cref="rand_seed(uint, uint)"/>.
		/// </summary>
/// <param name="s">the random number seed</param>
		/// <param name="i">each successive value increments index</param>
		/// <returns>void</returns>
		public static void rand_seed(uint s, uint i)
		{
			seed = s;
			index = i;
		}

The compiler knows that the return value is void. Why should the programmer
have to type it in twice? It's going to be something you have to force
programmers to do, rather than it coming naturally. Why should the
programmer have to identify the parameters twice? This could work:

/// The random number generator is seeded at program startup with a random
value.
/// This ensures that each program generates a different sequence of random
numbers.
/// To generate a repeatable sequence, use <see cref="rand_seed(uint,
uint)"/> to start the sequence.
/// The parameters start it, and each successive value increments index.
This means that the nth random
/// number of the sequence can be directly generated by passing index + n to
rand_seed(uint, uint)
public static void rand_seed(
        uint s,    /// the random number seed
        uint i)    /// each successive value increments index
{
seed = s;
index = i;
}

The idea is to make the compiler do the work rather than the programmer. So
while I agree completely with you on the advantages of doing this, I only
disagree with the form that C# and Javadoc take, as they are needlessly and
excessively klunky.

You have my vote for your suggested syntax. It looks good! Nice and simple. --AJG.
Aug 25 2005
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 25 Aug 2005 10:32:41 -0700, Walter wrote:

 I agree completely with you on the usefulness of automatic documentation
 generation from the source (after all, it fits right in with the idea of
 embedded contracts and unit tests). I just find the C# approach used to be
 overcomplicated and ugly in its source form. For example, instead of:
 
     /// <summary> starting seed </summary>
     private static uint seed;
 
 Wouldn't it be more natural as:
 
     private static uint seed;    /// starting seed

I agree in principle with you Walter. There is slight complication when you need multiple text lines to describe the item though. Maybe ... private static uint seed; /*/ Starting seed. This is automatically set to a different random value each time the application is run. /*/
 ? And:
 /// The random number generator is seeded at program startup with a random
 value.
 /// This ensures that each program generates a different sequence of random
 numbers.
 /// To generate a repeatable sequence, use <see cref="rand_seed(uint,
 uint)"/> to start the sequence.
 /// The parameters start it, and each successive value increments index.
 This means that the nth random
 /// number of the sequence can be directly generated by passing index + n to
 rand_seed(uint, uint)
 public static void rand_seed(
         uint s,    /// the random number seed
         uint i)    /// each successive value increments index
 {
 seed = s;
 index = i;
 }

Another complication is when you need to describe the result value. public static uint /// The current seed value. rand_seed( uint s, /// the random number seed uint i) /// each successive value increments index { uint o = seed; seed = s; index = i; return o; } This is starting to look hard to read. ;-) Yet another complication. I try hard to always include examples of usage in my documentation. As there is no built-in D syntax to describe examples (unittest is the closest) how could we put that into extractable form. Maybe we don't need to make that stand out from the rest of the docs, but often its useful to display example code in a different (monospace) font. ///Sample{ /// uint OldValue; /// OldValue = rand_seed( NewValue, theIndex); ///}
 The idea is to make the compiler do the work rather than the programmer. So
 while I agree completely with you on the advantages of doing this, I only
 disagree with the form that C# and Javadoc take, as they are needlessly and
 excessively klunky.

Very true.
 It wouldn't be too hard to adjust dmd to extract and output this info.

Well, off you go then ... by the end of next week would be just fine ;-) -- Derek Parnell Melbourne, Australia 26/08/2005 6:30:44 AM
Aug 25 2005
prev sibling parent reply "ElfQT" <dethjunk yahoo.com> writes:
I'm glad you agree with the use of it.
I don't force or promote c# style - I've used is as an example - any similar 
will suffice.
(Although I believe the c# style, or at least the different tags and all, is 
not a bad one - they already walked the path that we are on now, I will 
describe it later in this post.)

 /// <returns>void</returns>

programmer have to type it in twice?

value. its a description not a type indication. There's no meaning in documenting void (well, at least in most cases).
    private static uint seed;    /// starting seed

_and_ the end unmistakenly. (We need a standard on how to indicate multiple lines too.)
 /// ... long desc snipped by ElfQT...
 rand_seed(uint, uint)
 public static void rand_seed(
        uint s,    /// the random number seed
        uint i)    /// each successive value increments index

All right that looks good, even better from your expressed point of view, but consider that - this way you always have to break parameters to separate lines - maybe not everyone wants to write all the comment, it has to work with or without - you can't "collapse" (hide all the comments at once) - well at least you can collapse the "long", summarizing description. Aside of that the format is good - as any standard and well thought format is good. So, at the given msdn lib. link (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcoriX LDocumentation.asp) I recommend "Recommeded tags" - not to use them as copy it mindlessly, but as what possibilities are in such commenting. My short version: All tags are xml, so there is a open and a close (<c> </c>), I will only write the open as a "comment type". <c> and <code> indicating code (inside the comment block, not the actual code) <code> indicates multiple lines of code. <example> before the code, you can write about the following code This two (example and code) in a generated output can indicate formatted section of "Example" - description, and then example code. <include file='filename' path='tagpath[ name="id"]' /> - lets you refer to comments in another file. With <list> and <listheader> - well, guess you can make a list. <para> - paragraph Ok, you got me with this two - maybe formatting the comment (more precisely to control the output of the comment) is a bit strange. The goal with c# probably was to be able to generate msdn lib content, or very similar. Maybe D donesn't need that. <remarks> - well summary is planned to be short - that will appear on the fly with code editors. <remarks> is the long description - also there is a "Remarks" section in msdn doc style... <see> - lets you create links to other members <seealso> - the listing of "See also" sections links Not that interesting or important: <exception cref="member"> <param> - now we all know it, and will probably reject that format. <paramref> - but with this, you can refer to a given param <permission> - thats .net specific <value> - c# property specific Now I try to gather what is needed. Comment on structs, interfaces, classes, methods and functions, enums, typedefs, properties, templates. I recommend to use a summarizing form and an optional longer description for classes, methods and functions, maybe teampaltes also. I like the given simply form, but how to comment the return value? /// here comes a summary. it can /// multi line ///d long long long long ///d long long description ///r the meaning if the return value (if its not void) public static void rand_seed( uint s, /// the random number seed uint i) /// each successive value increments index Somehow we need to indicate (differentiate in the comment text): "description" (the long one, not the summary), comment on return value, link to another code element (class, enum, method etc.). Is there any more useful type of comment element? Does it need something to control documentation output like standard documentation sections (like <code>, <seealso>, <example>? Do we need triple slashes? Are these comments different from two slash standard comments? (I guess its easier to extract the triple ones, without exactly parsing and analyzing of the comment is at a place in the source, which place indicates if that comment is needed in the doc, or just a "simple" comment.) Also, any class level variable should use the commenting format - and clever tools should support that also (when moving the cursor to a use of that variable, or typing it, the info should appear.) Ok that was just my past midnight rambling started by the positive reaction - I will be glad even with a simple form without making short summary and longer description and without any of the rest (but still there is a need to comment on return value)). Also, now I found Derek's post pointing out multiline comment, and return value comment, and even example code. I dont like the linebreak with return value comment. Regards, ElfQT
Aug 25 2005
parent "Walter" <newshound digitalmars.com> writes:
What I'll do is write up a quick strawman document.
Aug 26 2005
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
<snip>
  <dt>uint <b>rand</b>()
  <dd>Get next random number in sequence.
  <p>
 
 </dl></dl>

Oh. I'd begun to assume the misplaced <p> tags dotted about the pages were a bug in your preprocessor. Looks like I was wrong. Welcome to HTML. The <p> tag marks the beginning of a paragraph, not the end of one. And it certainly doesn't belong /between/ elements of a list. There's also </p>, which marks the end of a paragraph, but that's optional.... Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 24 2005
parent reply "Uwe Salomon" <post uwesalomon.de> writes:
 There's also </p>, which marks the end of a paragraph, but that's  
 optional....

No, it isn't. It was optional. Nowadays everybody should write correct XHTML. Ciao uwe
Aug 24 2005
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Uwe Salomon wrote:
 
 There's also </p>, which marks the end of a paragraph, but that's  
 optional....

No, it isn't. It was optional. Nowadays everybody should write correct XHTML.

In order to start writing correct XHTML, one must start writing XHTML. Which means, first things first, that the document must identify itself as XHTML. Even if you ignore DOCTYPE declarations, a page cannot be both HTML and XHTML at the same time if it uses <img> or other tags that don't have closing versions. But still, there are people who feel it's good practice to include all the closing tags regardless. I do it myself. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 24 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
 Here's an example of how I use it, this is std_random.txt, the eventual html
 is at www.digitalmars.com/d/phobos/std_random.html
 
 The header, footer, and sidebar are all boilerplate from macros.inc.

Looks like the preprocessor at the moment is little more than a workaround for HTML not having client-side includes. For that matter, how do blocks of BNF or D code look in your input files? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 24 2005
parent "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:dehfu9$1ujl$1 digitaldaemon.com...
 Walter wrote:
 Here's an example of how I use it, this is std_random.txt, the eventual


 is at www.digitalmars.com/d/phobos/std_random.html

 The header, footer, and sidebar are all boilerplate from macros.inc.

Looks like the preprocessor at the moment is little more than a workaround for HTML not having client-side includes.

That's right. It's a trivial program, but very useful.
 For that matter, how do blocks of BNF or D code look in your input files?

$(CODE_S) void main() { writefln("hello world\n"); } $(CODE_E) That way, I can experiment with various schemes of marking code without having to edit hundreds of files. The macros are currently defined as: .set CCODE_S=<p><table border=0 cellspacing=2 cellpadding=8 bgcolor="#cccccc"> <tr bgcolor="#EEDDEE"><td width=600> \ <pre><font color="#000066" face="mono"> .set CCODE_E=</font></td></pre></tr></table><p> .set CODE_S=<p><table border=0 cellspacing=2 cellpadding=8 bgcolor="#cccccc"> \ <tr bgcolor="#e7e7e7"><td width=600> \ <pre><font color="#000066" face="mono"> .set CODE_E=</font></td></pre></tr></table><p> .set CODE_S=<p><table border=0 cellspacing=2 cellpadding=8 bgcolor="#cccccc"> \ <tr bgcolor="#e7e7e7"><td width=600> \ <pre><font color="#000066" face="mono"> .set CODE_E=</font></td></pre></tr></table><p> .set GRAMMAR_S=<p><table border=0 cellspacing=2 cellpadding=8 bgcolor="#cccccc"> \ <tr bgcolor="#FEFEFE"><td width=600> \ <pre><font color="#060666" face="mono"> .set GRAMMAR_E=</font></td></pre></tr></table><p>
Aug 24 2005