Philadelphia Reflections

The musings of a physician who has served the community for over six decades

1 Volumes

George IV

George IV and Computers(1)

I got him into computers around 1960. He soon far surpassed me.

New topic 2016-12-20 00:21:28 contents

The Evolution of a Programmer

High School/Jr.High

  10 PRINT "HELLO WORLD"
  20 END

First year in College

  program Hello(input, output)
    begin
      writeln('Hello World')
    end.

Senior year in College

  (defun hello
    (print
      (cons 'Hello (list 'World))))

New professional

  #include <stdio.h>
  void main(void)
  {
    char *message[] = {"Hello ", "World"};
    int i;
 
    for(i = 0; i < 2; ++i)
      printf("%s", message[i]);
    printf("\n");
  }

Seasoned professional

  #include <iostream.h>
  #include <string.h>
 
  class string
  {
  private:
    int size;
    char *ptr;
 
  string() : size(0), ptr(new char[1]) { ptr[0] = 0; }
 
    string(const string &s) : size(s.size)
    {
      ptr = new char[size + 1];
      strcpy(ptr, s.ptr);
    }
 
    ~string()
    {
      delete [] ptr;
    }
 
    friend ostream &operator <<(ostream &, const string &);
    string &operator=(const char *);
  };
 
  ostream &operator<<(ostream &stream, const string &s)
  {
    return(stream << s.ptr);
  }
 
  string &string::operator=(const char *chrs)
  {
    if (this != &chrs)
    {
      delete [] ptr;
     size = strlen(chrs);
      ptr = new char[size + 1];
      strcpy(ptr, chrs);
    }
    return(*this);
  }
 
  int main()
  {
    string str;
 
    str = "Hello World";
    cout << str << endl;
 
    return(0);
  }

Master Programmer

  [
  uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820)
  ]
  library LHello
  {
      // bring in the master library
      importlib("actimp.tlb");
      importlib("actexp.tlb");
 
      // bring in my interfaces
      #include "pshlo.idl"
 
      [
      uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820)
      ]
      cotype THello
   {
   interface IHello;
   interface IPersistFile;
   };
  };
 
  [
  exe,
  uuid(2573F890-CFEE-101A-9A9F-00AA00342820)
  ]
  module CHelloLib
  {
 
      // some code related header files
      importheader(<windows.h>);
      importheader(<ole2.h>);
      importheader(<except.hxx>);
      importheader("pshlo.h");
      importheader("shlo.hxx");
      importheader("mycls.hxx");
 
      // needed typelibs
      importlib("actimp.tlb");
      importlib("actexp.tlb");
      importlib("thlo.tlb");
 
      [
      uuid(2573F891-CFEE-101A-9A9F-00AA00342820),
      aggregatable
      ]
      coclass CHello
   {
   cotype THello;
   };
  };
 
 
  #include "ipfix.hxx"
 
  extern HANDLE hEvent;
 
  class CHello : public CHelloBase
  {
  public:
      IPFIX(CLSID_CHello);
 
      CHello(IUnknown *pUnk);
      ~CHello();
 
      HRESULT  __stdcall PrintSz(LPWSTR pwszString);
 
  private:
      static int cObjRef;
  };
 
 
  #include <windows.h>
  #include <ole2.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include "thlo.h"
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "mycls.hxx"
 
  int CHello::cObjRef = 0;
 
  CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk)
  {
      cObjRef++;
      return;
  }
 
  HRESULT  __stdcall  CHello::PrintSz(LPWSTR pwszString)
  {
      printf("%ws
", pwszString);
      return(ResultFromScode(S_OK));
  }
 
 
  CHello::~CHello(void)
  {
 
  // when the object count goes to zero, stop the server
  cObjRef--;
  if( cObjRef == 0 )
      PulseEvent(hEvent);
 
  return;
  }
 
  #include <windows.h>
  #include <ole2.h>
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "mycls.hxx"
 
  HANDLE hEvent;
 
   int _cdecl main(
  int argc,
  char * argv[]
  ) {
  ULONG ulRef;
  DWORD dwRegistration;
  CHelloCF *pCF = new CHelloCF();
 
  hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
 
  // Initialize the OLE libraries
  CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
  CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER,
      REGCLS_MULTIPLEUSE, &dwRegistration);
 
  // wait on an event to stop
  WaitForSingleObject(hEvent, INFINITE);
 
  // revoke and release the class object
  CoRevokeClassObject(dwRegistration);
  ulRef = pCF->Release();
 
  // Tell OLE we are going away.
  CoUninitialize();
 
  return(0); }
 
  extern CLSID CLSID_CHello;
  extern UUID LIBID_CHelloLib;
 
  CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */
      0x2573F891,
      0xCFEE,
      0x101A,
      { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
  };
 
  UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */
      0x2573F890,
      0xCFEE,
      0x101A,
      { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
  };
 
  #include <windows.h>
  #include <ole2.h>
  #include <stdlib.h>
  #include <string.h>
  #include <stdio.h>
  #include "pshlo.h"
  #include "shlo.hxx"
  #include "clsid.h"
 
  int _cdecl main(
  int argc,
  char * argv[]
  ) {
  HRESULT  hRslt;
  IHello        *pHello;
  ULONG  ulCnt;
  IMoniker * pmk;
  WCHAR  wcsT[_MAX_PATH];
  WCHAR  wcsPath[2 * _MAX_PATH];
 
  // get object path
  wcsPath[0] = '\0';
  wcsT[0] = '\0';
  if( argc > 1) {
      mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1);
      wcsupr(wcsPath);
      }
  else {
      fprintf(stderr, "Object path must be specified\n");
      return(1);
      }
 
  // get print string
  if(argc > 2)
      mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1);
  else
      wcscpy(wcsT, L"Hello World");
 
  printf("Linking to object %ws\n", wcsPath);
  printf("Text String %ws\n", wcsT);
 
  // Initialize the OLE libraries
  hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
  if(SUCCEEDED(hRslt)) {
 
 
      hRslt = CreateFileMoniker(wcsPath, &pmk);
      if(SUCCEEDED(hRslt))
   hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello);
 
      if(SUCCEEDED(hRslt)) {
 
   // print a string out
   pHello->PrintSz(wcsT);
 
   Sleep(2000);
   ulCnt = pHello->Release();
   }
      else
   printf("Failure to connect, status: %lx", hRslt);
 
      // Tell OLE we are going away.
      CoUninitialize();
      }
 
  return(0);
  }

Apprentice Hacker

  #!/usr/local/bin/perl
  $msg="Hello, world.\n";
  if ($#ARGV >= 0) {
    while(defined($arg=shift(@ARGV))) {
      $outfilename = $arg;
      open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n";
      print (FILE $msg);
      close(FILE) || die "Can't close $arg: $!\n";
    }
  } else {
    print ($msg);
  }
  1;

Experienced Hacker

  #include <stdio.h>
  #define S "Hello, World\n"
  main(){exit(printf(S) == strlen(S) ? 0 : 1);}

Seasoned Hacker

  % cc -o a.out ~/src/misc/hw/hw.c
  % a.out

Guru Hacker

  % echo "Hello, world."

Thanks to http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html

Book Proposal: Investing

Web Standards Validation

There are two primary aspects of a website that need validation:



1. (X)HTML

You can use the W3C's QA Markup Validation Service.
The URL to test the main page of Philadelphia Reflections is http://validator.w3.org/

Firefox has several useful add-ons for (X)HTML validation; one that uses Tidy is here: Html Validator

2. CSS

The W3C has a validation service for CSS, too.
For Philadelphia Reflections, the following URL checks all the CSS definitions in the main page: http://jigsaw.w3.org/css-validator/ (note: this validator is a little flakey: it produces different answers for the same file; you have to refresh a couple of times to get the whole story)

Firefox has several useful web developer add-on tools; try this one: Web Developer


Once you've gotten the HTML and CSS basics under control, there are other aspects of your site that you will want to validate:

Broken Links

The W3C will check all your links for both response time and validity.
http://validator.w3.org/checklink/checklink

Tidy

There is an absolutely lovely program called HTML Tidy, origianlly written by Dave Raggett and decribed by the W3C here: http://www.w3.org/People/Raggett/tidy/

Calls to Tidy are available in some newer renditions of PHP (sadly, not the one we are using), however, on Widows (only) versions of Firefox and Mozilla, you can download an extension that will provide all the Tidy functions in your browser! ... https://addons.mozilla.org/firefox/249/. This a fantastic feature that I use all the time.

Syndication XML Validation

Validating RSS and Atom files is greatly facilitated by http://feedvalidator.org/. It has a number of quirks, the worst of which is that it has a length limitation that we exceed and so we have to provide "short" syndication files since all the feed aggregators use this facility and reject any feeds that aren't validated by it.

Google Sitemap Validation

If you submit a sitemap to Google through their Webmaster Tools facility they will validate your sitemap when they load it. An external validation tool is available here: Validome Google Sitemap(s) Validator

Yahoo and Microsoft have agreed to support Google's Sitemap protocol and to support the inclusion of the line "Sitemap: http://www.philadelphia-reflections.com/sitemap.xml" in robots.txt. If other search engines adopt this facility it will make it much easier to get into the world's many search engines ... they'll pick up this line instead of us having to hunt them down.

Meta Tag Validator

As you puzzle the mysteries of search-engine indexing, you'll want to check your meta tags: http://www.widexl.com/remote/search-engines/metatag-analyzer.html

gzip Compression & Headers

When you start getting really fancy and want to include automatic gzip compression, you'll want to see it in action and you'll want to check out all of your HTTP headers: http://www.gidnetwork.com/tools/gzip-test.php

Response Time

Of course, the reason you''re experimenting with gzip is because you're concerned about response time.
(1) Try this site for a detailed analysis: http://www.websitepulse.com/help/tools.php
(2) Firefox to the rescue again: FasterFox is another lovely add-in: https://addons.mozilla.org/firefox/1269/

Geo Tags

Check the validity of your geo tags here: Geo-Tag Validator

Big List

http://uitest.com/en/analysis/ is the mother of all lists of validations routines

Floating Three-Column CSS Layout

A current fad in web page styling is to use CSS exclusively to define the basic page sections. The "old" way of doing this was to use tables, but that's no longer stylish. Instead, we are exhorted to use CSS exclusively.

A very common page layout has a head and a foot with three columns sandwiched in between. Philadelphia Reflections uses this layout.

Most descriptions of this layout style that I have found Googling around the Internet involve absolute positioning which very often does not adapt well to differing screen sizes and browser window sizes. What we use here makes use of floating columns, which re-size themselves very nicely.

Several anomalies and quirks should be noted:

These quirks and anaomalies make me think that maybe this either isn't quite kosher or else may be superceded by later CSS definitions. But for the time being, this works very happily and both the HTML and the CSS validate perfectly well.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <title> Floating Three-column CSS example</title>

    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<style type="text/css">


 #head {
  background-color:blue;
  color:white;
  text-align:center;
  }

 #wrap {
  }

 #left {
  float:left;
  width: 30%;
  }

 #right {
  float:right;
  width:30%;
  }

 #center {
  }

 #clear {
  clear:both;
  }

 #foot {
  background-color:red;
  color:white;
  text-align:center;
  }

</style>
  </head>

  <body>

    <div id="head">
      <p>Head</p>
    </div>

    <div id="wrap">

      <div id="left">
        <p>Left</p>
      </div>

      <div id="right">
        <p>Right</p>
      </div>

      <div id="center">
        <p>Center</p>
      </div>

      <div id="clear"></div>

    </div>

    <div id="foot">
      <p>Foot</p>
    </div>

  </body>
</html>

Valid XHTML YouTube embed code generator

XHTML vs. HTML

The markup language used by web browsers continues to evolve. The most current version (as of April 2009) is XHTML 1.1, an XML version of HTML.

Many browsers, most particularly IE, do not support XHTML. Technically speaking, they support only the "text/html" mime type, not "application/xhtml+xml". Lots of web developers have gone to the trouble of sticking closing tags ( />) in their BR, HR, META and INPUT tags and a DOCTYPE at the top but then serve the code as "text/html".

This produces a syntactic mish mash which may be worse than using strict HTML 4.01.

Why "worse"? Because of the possibility of unintended results from providing incorrect instructions to the browser. If you care about the output produced by the browser, which most developers and content providers emphatically do, then you have to be careful about what instructions you give the browser. You simply cannot count on getting what you want if what you're telling the browser to do is syntactically incorrect.

However, it's a little difficult to see just what good XHTML is:

Internet cognoscenti speak disparagingly of "tag soup" but the Internet is a lot more about content than it is about syntax, so who really cares?

Well, somehow, I do. A little. Since we use PHP on this site, we have the opportunity to figure out what features are supported by a browser and render the correct types of tags, mime-types, etc.

Check out the HTTP headers and the page source to see the following script in action:

  1. It renders XHTML 1.1 whenever it encounters a browser that can support it
  2. It uses output buffering (which demonstrably if illogically improves rendering response time)
  3. It sends the whole thing using gzip compression if the browser will support it
  4. But also, it concedes certain issues based on experience for the sake of a smoothly-operating website
<?php
//
//  This script figures out what kind of mime type (HTML vs XHTML) the browser supports and sends the correct headers
//  It also initiates compression, specifies cache-ing and sends other <meta http-equiv headers
// 
//  My thanks to http://www.workingwith.me.uk/articles/scripting/mimetypes for the basic idea and structure
// 
//  $_SERVER["ACCEPT"] describes the mime_types a browser supports in a comma-separated list:
// 
//    mime_type,mime_type,mime_type
// 
//  If a browser prefers one mime_type or group of mime_types, it adds a q-value
// 
//    mime_type,mime_type;q=x.x, mime_type,mime_type,mime_type,...,mime_type;q=x.x
// 
//  The q-value is a number between 0.0 and 1.0 ... the higher the number, the greater the preference
//  The idea is that if we can serve more than one mime_type we should serve the browser's higher preference
//
//  ob_start("ob_gzhandler"); does all the work to compress the output if the browser can handle it
//  ob_start("fix_code"); calls the "fix_code" function instead, so initiating gzip is my responsibility
//
//  $_SERVER["HTTP_USER_AGENT"] is an opaque decription of the browser itself
//
//  $_SERVER['HTTP_ACCEPT_ENCODING'] describes compression capabilities
//
//  I output these three variables as an HTML comment so I can debug things more easily
//
//  Despite my desire to do things "right", you will see I accomodate myself to the reality of user-supplied content 
//  and browser peculiarities in order to have a working website
//

function fix_code($buffer)
  {
  #
  # Called for HTML browsers to delete all the lovely close-brackets
  # it's up to me to initiate the gzipping because ob_start is called by "fix_code" instead of "ob_gzhandler"
  #
  if (stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))
    {
    header("Content-Encoding: gzip"); // notifies the far-end to un-gzip 
    return (gzencode(str_replace(" />", ">", $buffer),6,FORCE_GZIP));
    }
    else
      {
      return (str_replace(" />", ">", $buffer));
      }
  }

#
# default values
#
$charset          = "UTF-8";       # See http://en.wikipedia.org/wiki/UTF-8
$mime             = "text/html";   # Plain vanilla
$cache_control    = "max-age=200"; # Cache expires after 200 seconds

$xhtml_q          = 0;
$html_q           = 0;

# see http://www.w3.org/QA/2002/04/valid-dtd-list.html
$DOCTYPE_xhtml11  = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>\n"; 
$DOCTYPE_xhtml10  = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n";
$DOCTYPE_wap      = "<!DOCTYPE html PUBLIC '-//WAPFORUM//DTD XHTML Mobile 1.2//EN' 'http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd'>\n";
$DOCTYPE_html401  = "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n";
$DOCTYPE_html401l = "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n";

$html_xhtml       = "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>\n\n";
$html_iphone      = "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' manifest='iphone.manifest'>\n\n";
$html_html401     = "<html lang='en'>\n\n";
$html_html401_IE  = "<html lang='en' xmlns:v='urn:schemas-microsoft-com:vml'>\n\n";  # xmlns:v='urn:schemas-microsoft-com:vml' is recommended by Google for maps display using IE
$html_plain       = "<html>\n\n";

# parental control tag
$pics_Label       = '(pics-1.1 "http://www.icra.org/pics/vocabularyv03/" l 
	gen true for "http://philadelphia-reflections.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://www.philadelphia-reflections.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://search.freefind.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://www.search.freefind.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://statcounter.com" r (n 0 s 0! v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://www.statcounter.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://c3.statcounter.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0) 
	gen true for "http://www.c3.statcounter.com" r (n 0 s 0 v 0 l 0 oa 0 ob 0 oc 0 od 0 oe 0 of 0 og 0 oh 0 c 0))';

# I include the following HTML comment for my ongoing debugging purposes
$show_info        = "<!-- \nHTTP_USER_AGENT      $_SERVER[HTTP_USER_AGENT]\nHTTP_ACCEPT_ENCODING $_SERVER[HTTP_ACCEPT_ENCODING]\nHTTP_ACCEPT          $_SERVER[HTTP_ACCEPT]\n -->\n\n";

# note that I eval $prolog_type below so that the xml header (if any) gets the right charset
$prolog_type      = '$DOCTYPE_html401l $html_plain $show_info';

#
# the logic
# 

# W3C Validator
if (stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator")) 
  {
  ob_start("ob_gzhandler");
  $mime        = "application/xhtml+xml";
    # UTF-8 produces character-type errors
    $charset     = "iso-8859-1";
  $prolog_type = '$xml_header $DOCTYPE_xhtml11 $html_xhtml $show_info';
  }
  else
    {
    # fancy wap-enabled handheld device
    if(stristr($_SERVER["HTTP_ACCEPT"],"application/vnd.wap.xhtml+xml")) 
      { 
      ob_start("ob_gzhandler");
        # per http://www.ready.mobi/ and http://www.w3.org/TR/mobileOK-basic10-tests/ application/xhtml+xml is preferred
//      $mime        = "application/vnd.wap.xhtml+xml";
        $mime        = "application/xhtml+xml";
      $prolog_type = '$xml_header $DOCTYPE_wap $html_plain $show_info';
      }
      else
        {
        # non-wap xhtml-enabled browser
        if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) 
          { 
          # retrieve the q values for "application/xhtml+xml" and "text/html"

          if (preg_match('%application/xhtml\+xml[^;]*?;q=([1|0]\.[1-9]+)%i', $_SERVER["HTTP_ACCEPT"], $matches)) 
            {
            $xhtml_q = (float)$matches[1];
            }

          if (preg_match('%text/html[^;]*?;q=([1|0]\.[1-9]+)%i', $_SERVER["HTTP_ACCEPT"], $matches)) 
            {
            $html_q = (float)$matches[1];
            }

          # if the q value for HTML is greater than for XHTML
          # then treat output as HTML 4.01 strict (Opera 9.64, for instance)

          if($html_q > $xhtml_q) 
            {
            ob_start("fix_code");
            $mime        = "text/html";
              # UTF-8 produces character-type errors
              $charset     = "iso-8859-1";
            $prolog_type = '$DOCTYPE_html401 $html_html401 $show_info';
            }

            # otherwise, go with XHTML
            else
              {
              ob_start("ob_gzhandler");
                # for the time-being application/xhtml+xml is too strict for us: unless your tags are PERFECT, it blows up
//              $mime        = "application/xhtml+xml";
                $mime        = "text/html";
                # UTF-8 produces character-type errors
                $charset = "iso-8859-1";

              # see "Safari Web Content Guide for iPhone OS" for cache manifest description
              if (stristr($_SERVER["HTTP_USER_AGENT"],"iPhone")) 
                {
                $prolog_type = '$xml_header $DOCTYPE_xhtml11  $html_iphone $show_info';
                }
                else
                 {
                  $prolog_type = '$xml_header $DOCTYPE_xhtml11  $html_xhtml $show_info';
                 }
              }
            }
          
          else
            {
            # plain text/html browser
            if(stristr($_SERVER["HTTP_ACCEPT"],"text/html")) 
              { 
              ob_start("fix_code");
              $mime        = "text/html";
                # UTF-8 produces character-type errors
                $charset     = "iso-8859-1";
              $prolog_type = '$DOCTYPE_html401 $html_html401 $show_info';
              }
              else
                {
                # if the browser doesn't specify any X/HTML mime type, treat like HTML 4.01 Transitional (IE 7, for instance)
                ob_start("fix_code");
                $mime        = "text/html";
                  # UTF-8 produces character-type errors
                  $charset     = "iso-8859-1";
                $prolog_type = '$DOCTYPE_html401l $html_plain $show_info';
                # if IE then include Google's recommended "xmlns:v  ..." 
                if(stristr($_SERVER["HTTP_USER_AGENT"],"MSIE")) 
                  {
                  $prolog_type = '$DOCTYPE_html401l $html_html401_IE $show_info';
                  }
                }
            }
        }
    }

#
# output the mime type, prolog type and other <meta http-equiv= variables
#
header("Content-Type: $mime; charset=$charset");
header("Content-Language: en-us");
header("Vary: Accept");

header("Cache-Control: $cache_control");

header("Content-Script-Type: text/javascript");
header("Content-Style-Type: text/css");
header("imagetoolbar: no");

// parental controls from http://www.icra.org/
header("pics-Label: $pics_Label");

// privacy header created at http://www.p3pwiz.com/
header("P3P: policyref=\"http://www.philadelphia-reflections.com/w3c/p3p.xml\", CP=\"NID DSP NOI COR\"");

$xml_header       = "<?xml version='1.0' encoding='$charset' ?>\n";
eval("\$prolog_type = \"$prolog_type\";");

print $prolog_type;
?>

Here's an interesting article on Doctype Switching: http://gutfeldt.ch/matthias/articles/doctypeswitch.html

The Philadelphia Reflections webmaster: George IV

(my thanks to http://centricle.com/tools/html-entities/ for HTML encoding)

HTML Forms

How do you (a) open a form when a radio button is clicked (b) in a new window?

Here's how it's done on this website.

<html>
<head>

<script type="text/javascript">

	/* javascript function called by the radio buttons 
	     to submit the form when clicked */

	function formSubmit()
	{
	document.getElementById("form_x").submit()
	}
	
</script>

</head>
<body>

  <form name="form_x" id="form_x"
	action="some_routine.php"
	target="newIMGwin"
	method="post" 
	style="whatever">

	<fieldset>
	<legend>legend surrounding the form</legend>

	<input type="radio" name="key" value="1269" onclick="formSubmit()" />

	</fieldset>
  </form>

</body>
</html>

(my thanks to http://centricle.com/tools/html-entities/ for HTML encoding)

Sold Out

SMTP Authorization and Handling Bounced Emails with PEAR Mail

Recently our ISP started requiring user sign on in order to send emails. PHP's mail function stopped working as a result.

Naturally, the ISP did not notify us of this change so we were quite surprised when many thousands of emails on our newsletter list were rejected (every one of them, in fact).

What error message was returned to us to notify us of what the problem was? Why this helpful note:

Mail sent by user nobody being discarded due to sender restrictions in WHM->Tweak Settings

Doesn't that just say it all?

I'm being snide, but our ISP is really quite good about keeping its software up to date and aside from an occasional surprise like this, they are very reliable. Being up to date including the automatic incorporation of the PEAR Mail facility which we are now using.

PEAR's Mail system works quite well but two problems were very vexing until we stumbled our way to a solution:

  1. How, exactly, do we sign on to the SMTP server?
  2. How do we ensure that bounced emails (the bane of all email lists) get returned to us?

You might not think that the first question would be so hard but it actually took a good deal of trial and error to get it right. As for the second question, there is an awful lot of wrong information available out in Internet land (including but not limited to VERP and XVERP which I advise you to avoid).

With PEAR Mail you first set up a "factory" and then send emails, either singly or in a loop. We keep the user id, password, etc. in a file "above" the web server in hopes that will keep them a secret ... here's the code (it actually is in production and it does in fact work):

<?php
include('Mail.php');

# the email constants are contained in a file outside the web server
include("/level1/level2/level3/constants.php");

$headers = array (
         'From' => '"name"<addr@domain.com>',
         'Sender' => '"name"<addr@domain.com>',
         'Reply-To' => '"name"<addr@domain.com>',
         'Return-Path' => 'addr@domain.com',
         'Content-type' => 'text/html; charset=iso-8859-1',
         'X-Mailer' => 'PHP/' . phpversion(),
         'Date' => date("D, j M Y H:i:s O",time()),
         'Content-Language' => 'en-us',
         'MIME-Version' => '1.0'
         );

// call the PEAR mail "factory"
$smtp = Mail::factory('smtp',
      array (
            'host' => EMAIL_HOST,
            'port' => EMAIL_PORT,
            'auth' => true,
            'username' => EMAIL_USERNAME,
            'password' => EMAIL_PASSWORD,
            'persist' => true,
            'debug' => false
            ), '-f addr@domain.com'
      );

# to send emails:
#
# $headers['To']      = $to;        # provide the "$to" variable, something like $to = '"name"<addr@domain.com>';
#                                   # note that the first parameter of $smtp->send can be "decorated" this way or just a naked email address
# $headers['Subject'] = $subject;   # provide the "$subject" variable
# $mail = $smtp->send($to, $headers, $contents_of_the_email);
#                          -------- ................................> except for 'To' and 'Subject',
#                                                                     $headers is provided by this module but can be over-ridden
# if (PEAR::isError($mail))
# {
#   echo "<p style='color:red;'>The email failed; debug information follows:<br />";
#   echo $mail->getDebugInfo() . "<br />";
#   echo $mail->getMessage()   . "</p>";
# }
# else
# {
#   echo "<p>email successfully sent</p>";
# }

?>

My thanks to http://htmlentities.net/ for the HTML entites conversion.

Data Sources for Health Care

OTHER REVENUE PROVIDERS WITH POTENTIALLY USEFUL MEDICAL DATA, MOSTLY UNUSED

Although some research discoveries are stumbled on by accident, most of the important ones derive from asking the right questions. If you don't ask the right question, you can wander around in a laboratory white coat for a lifetime without discovering much that is worth knowing. We already have huge stores of data, much of it in electronic form, about the health system. It mostly comes from people paying bills:

Health Insurance

Health Savings Accounts

Payroll deductions for Medicare

Medicare premiums

Military Medical Systems

Veterans Administration

Government subsidies to Hospitals

Medicaid (50-70% Federal)

Social Security

Life Insurance

Premium Investment Income

Cash payments (weak source)

Unclassified Remainder

To summarize the data sources already in existence raises questions of privacy and overwhelming government intrusion into the lives of citizens. That might well be a threat in forty or fifty years, but the disaster of the Health Insurance Exchanges trying to use a small particle of this data is reassuring, in a discouraging sort of way. These systems were originally devised to ask questions of no great relevance to national health costs, so they pose no great temptation to a wandering medical snooper. But they almost always have to meet some sort of an annual budget, so the answer to the question we are now asking is mostly available to everybody, on the Internet. It should be comparatively easy to learn, with adequate accuracy, how much is being spent on what kind of person, right now. If the total comes anywhere near 18% of GDP, we have as much detail as we need for this book to defend the conclusions it draws. We can tell the gross amounts, and by dividing by 350 million, get the average per person costs. Apportionment by age is somewhat less precise, but the numbers are so large, age stratification can be fairly accurately estimated. Let's start with a question we think we know the answer to.

Website Test Results

The site www.webpagetest.org is an excellent facility for testing the performance of a web site. Philadelphia Reflections passes with flying colors:

{Response time test with lots of images}
Response time test with lots of images

REFERENCES


Excellent site for website testing www.webpagetest.org

CNBC Exposed

This series of videos is the best insight into America's financial reporting you will ever find.












Here's the weasel talking to another weasel



Macroeconomics of The 2007 Collapse

Sudden wealth creation, whether from the discovery of gold or oil, the conversion of poverty into useful cheap labor, or the sudden abundance of cheap credit, is of course a good thing. Sudden wealth creation can be compared with a stone thrown into a pond, causing a splash, and ripples, but leaving a somewhat higher water level after things calm down. The globalization of trade and finance in the past fifty years has caused 150 such disturbances, mostly confined to a primitive developing country and its neighbors. Only the 2007 disruption has been large enough to upset the biggest economies. It remains to be seen whether a disorder to the whole world will result in a revised world monetary arrangement. One hopes so, but national currencies, tightly controlled by local governments, have been successful in the past in confining the damage. This time, the challenge is to breach the dikes somewhat, without letting destructive tidal waves sweep past them. Many will resist this idea, claiming instead it would be better to have higher dikes.

It is the suddenness of new wealth creation in a particular region which upsets existing currency arrangements. Large economies "float" their currencies in response to the fluxes of trade, smaller economies can be permitted to "peg" their currencies to larger ones, with only infrequent readjustments. Even the floating nations "cheat" a little, in response to the political needs of the governing party, or, to stimulate and depress their economies as locally thought best. All politicians in all countries, therefore, fear a strictly honest floating system, and their negotiations about revising the present system will surely be guilty of finding loopholes for each other; the search for flexible floating will, therefore, claim to seek an arrangement which is "workable".

In thousands of years of governments, they have invariably sought ways to substitute inflated currency for unpopular taxes. The heart of any international payment system is to find ways to resist local inflation strategies. Aside from using gunboats, only two methods have proven successful. The most time-honored is to link currencies to gold or other precious substances, which has the main handicap of inflexibility in response to economic fluctuations. After breaking the link to gold in 1971, central banks regulated the supply of national currency in response to national inflation, so-called "inflation targeting". It worked far better than many feared, apparently allowing twenty years without a recession. It remains to be investigated whether the substitution of foreign currency defeated the system, and therefore whether the system can be repaired by improving the precision of universal floating, or tightening the obedience to targets, or both. These mildest of measures involve a certain surrender of national sovereignty; stronger methods would require even more draconian external force. The worse it gets, the more likely it could be enforced only by military threat. Even the Roman Empire required gold and precious metals to enforce a world currency. The use of the International Monetary Fund (IMF) implies attempts to dominate the politics of the IMF. So it comes to the same thing: this crisis will have to get a lot worse, maybe with some rioting and revolutions, before we can expect anything more satisfactory than a rickety negotiated international arrangement, riddled with embarrassing "earmarks". Economic recovery will be slow and gradual unless this arrangement is better, or social upheavals worse, that would presently appear likely.

Existing Websites Which Offer Higher Education

Immense: Here are a few of my favorites--

http://www.khanacademy.org/

http://academicearth.org/

http://videolectures.net/

http://ocw.mit.edu/OcwWeb/web/home/home/index.htm

http://mitworld.mit.edu/browse

http://www.youtube.com/user/MIT

http://watch.mit.edu/

http://numericalmethods.eng.usf.edu/

http://www.apple.com/education/itunes-u/whats-on.html

Regex URL Matching

On this site we check for the existence of a URL whenever an entry is updated

There are two key technologies at work


function url_exists($url) 
{
// 
// checks whether a URL actually exists on the Internet
//
$handle   = curl_init($url);
if (false === $handle)
   {
    return false;
   }
curl_setopt($handle, CURLOPT_HEADER, false);
curl_setopt($handle, CURLOPT_FAILONERROR, true); 
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, false);
$connectable = curl_exec($handle);
curl_close($handle);   
return $connectable;
}


function aExists($matches)
{
//
// function called by preg_replace_callback
//
// $matches[0] is the complete match
// $matches[1] the match for the first subpattern
//	enclosed in '(...)' and so on

//
// checks to see if a regular link exists
// something similar is done for img src= also
//

$srcURL = $matches[3];
		
if (url_exists($srcURL)) {do something; return "";}  
else {do something else; return "";}
}

$foo = preg_replace_callback(
            '/(.*?)(<a .*?href=")([^"]*)("[^>]*>)(.*?)(<\/a>)/i',
            "aExists",
            $source_string);

(my thanks to http://centricle.com/tools/html-entities/ for HTML encoding)

Health Expenditures as a percent of GDP

My thanks to the US Census Bureau for this information.

The 2008 Statistical Abstract/International Statistics: Vital Statistics, Health, Education

http://www.census.gov/compendia/statab/cats/international_statistics/vital_statistics_health_education.html


Let's make a couple of comments. Health expenditure as a percent of GDP is a ratio. If health expenditures go up or down while GDP remains the same, the ratio goes up or down. But if GDP goes down or up and health expenditures remain the same, then the reverse is true. In the present atmosphere of slanted debate, America is being compared with France. If we compared the state of Mississippi with France, we would get a different opinion about France. If we compare Ukraine with America, we get a different opinion about our expenditures. It really does seem more appropriate to compare America with Europe as a whole, rather than allow the comparison to be selective in its choice of the sections of Europe under comparison.

The point is this: if you add in the poorer sections of Europe, you reduce the average GDP of the nation (Europe) you compare with America, and hence you increase the expenditures for health care as a proportion of European GDP. At the same time, you would have to add in the average expenditures of the poorer sections of Europe, which will lower the average health expenditures per GDP unit. With twenty-seven different countries included under the heading of "Europe", you can seem to illustrate just about any conclusion you intend to reach, just by modifying the mixture. The same is true of taking different states or sections of the USA. Minnesota is considerably cheaper than Florida, and the quality of health care is if anything superior.

Health officials have puzzled about this discrepancy between Minnesota and Florida for at least forty years, ever since Medicare costs were available to sort by zip code. If we still can't understand the difference between Minnesota and Florida, there is little validity in drawing much health insurance conclusion from a comparison of USA data with that of France. Comparing USA data with the whole of the European community could result in some sort of opinion about national budgets, but nothing but quarrels if conclusions are reached about the nature of local health insurance. When we finally figure out what the same data about Minnesota and Florida means, perhaps that could be a starting place for further explorations. In case you haven't noticed, Minnesota and Florida share the same Medicare insurance.

Forbidden SNL Clip



NBC pulled the original of this Saturday Night Live video from their Web site and replaced it with this edited version.

NBC deleted the section in which Herbert and Marion Sandler described swindling their clients and ultimately Wachovia. The original video had a caption that described the couple as "People who should be shot." Furthermore, the actor portraying Herbert Sandler said "And thank you, Congressman Frank, as well as many Republicans for helping block Congressional oversight of our corrupt activity."

Herbert and Marion Sandler sold Golden West Financial Corp to Wachovia in 2006 for $24 billion, precipitating Wachovia's failure and eventual sale to Wells Fargo.

Webpage Printing

This site offers a Print button for all Reflections and Topics. Formatting the text on the pages to print nicely works quite well; but how to specify what to do with images remains a bit unclear (as of August 2006). Although 95% of users employ Internet Explorer because Microsoft supplies it free with new computers, IE is just about the worst browser to use for printing. Safari is much better, and Firefox is pretty good. Opera is also satisfactory, but Internet Explorer is not recommended. The other browsers are free; find them in Google and download them. For the usual user, that's all you have to know.

If you are curious about the technicalities, read on. The "trick", if it can be called that, to special print formatting is the media attribute for CSS styling. The main stylesheet for this website is called in a LINK statement as follows:

<link rel="stylesheet" type="text/css" media="all" href="stylesheets/reflectionsLayout.css">

The media attribute tells the browser to use this sylesheet for all media types, i.e., for screens and printers. In the pages that are formattted to print is a stylesheet that cascades below the main stylesheet and therefore supercedes it. This stylesheet controls the printing. IE seems to have its own views on font size so we use some conditional comments to coax it to our way of thinking.

Here and there throughout the website are pages that contain onscreen navigation ("jump to top" and that sort of thing). We hide them when printing by saying class="navstrip" which you can see will result in those elements being hidden.

The specification of

<body onload="window.print()">

(all lower case for XHTML purposes) is what forces the print dialog to appear.

The remaining problem is how to specify CSS formatting for images so that text flows around them as we want. The formatting seems to work on screen for all browsers but only on some browsers for printing.

<style type="text/css" media="print">

  body        { margin: 0; padding: 0; width: 100%; }				
				
    #wrapper    { margin: 0; padding: 0; width: 100%; }
		
      #center     { margin: 0; padding: 0; }

      #content    { font-size: 11pt; line-height: 100%; font-family: "Times New Roman", Times, serif; }

        .navstrip   { visibility: hidden; }
				
</style>

<!--[if IE]>
<style type="text/css" media="print">

      #content    { font-size: 14pt; }
				
</style>
<![endif]-->

(my thanks to http://centricle.com/tools/html-entities/ for HTML encoding)

RSS, Atom, Syndication, etc.

The world is full of XML and XML-like file formats for syndication purposes

Here's the list of files we generate automatically for submission to search engines and such.

(For right now, things are a bit abbreviated)

http://www.philadelphia-reflections.com/reflectionsRSS.xml (RSS Syndication file)
http://www.philadelphia-reflections.com/reflectionsATOM.xml (Atom Syndication file)
http://www.philadelphia-reflections.com/sitemap.xml (Google sitemap)
http://www.philadelphia-reflections.com/siteinfo.xml (A9/Amazon siteinfo.xml)
http://www.philadelphia-reflections.com/reflectionsIDIF1.xml (Yahoo IDIF file 1)
http://www.philadelphia-reflections.com/reflectionsIDIF2.xml (Yahoo IDIF file 2)
http://www.philadelphia-reflections.com/reflectionsIDIF3.xml (Yahoo IDIF file 3)
http://www.philadelphia-reflections.com/reflectionsIDIF4.xml (Yahoo IDIF file 4)
http://www.philadelphia-reflections.com/reflectionsIDIF5.xml (Yahoo IDIF file 5)
http://www.philadelphia-reflections.com/IDIFpointer.txt (Yahoo IDIF pointer file)
http://www.philadelphia-reflections.com/urllist.txt (Yahoo urllist.txt)

Validate Short RSS | The Short RSS File itself
Validate Short rss (lower case) | The Short RSS File itself (lower case)
Validate Short ATOM | The Short ATOM File itself

Weblogs.com extended successfully pinged
Weblogs.com successfully pinged
blo.gs successfully pinged
Technorati successfully pinged
Ping-O-Matic successfully pinged
Syndic8 successfully pinged (Feed ID 477463)

Ping Blogroller manually
Ping MyYahoo manually



The RSS and Atom validator (http://feedvalidator.org/) has a length restriction. I don't know what it is, exactly, but it bombs if your file is "too long". Since most syndication readers run the validator before they'll accept a feed, I have resorted to creating a short file, which is what I point to in my meta tags.



Here's how I provide change frequency and priority for our Google sitemap (in PHP ... $mod is the variable containing the date last modified)

$GOOGLEpriority = "0.0"; $GOOGLEfreq = "yearly";	// default

if ($mod > mktime(0,0,0) - 86400*210)	{$GOOGLEpriority = "0.1"; $GOOGLEfreq = "monthly";}	// past 210 days
if ($mod > mktime(0,0,0) - 86400*180)	{$GOOGLEpriority = "0.2"; $GOOGLEfreq = "monthly";}	// past 180 days
if ($mod > mktime(0,0,0) - 86400*150)	{$GOOGLEpriority = "0.3"; $GOOGLEfreq = "monthly";}	// past 150 days
if ($mod > mktime(0,0,0) - 86400*120)	{$GOOGLEpriority = "0.4"; $GOOGLEfreq = "monthly";}	// past 120 days
if ($mod > mktime(0,0,0) - 86400*90)	{$GOOGLEpriority = "0.5"; $GOOGLEfreq = "monthly";}	// past 90 days
if ($mod > mktime(0,0,0) - 86400*60)	{$GOOGLEpriority = "0.6"; $GOOGLEfreq = "monthly";}	// past 60 days
if ($mod > mktime(0,0,0) - 86400*30)	{$GOOGLEpriority = "0.7"; $GOOGLEfreq = "monthly";}	// past 30 days
if ($mod > mktime(0,0,0) - 86400*7)	{$GOOGLEpriority = "0.8"; $GOOGLEfreq = "weekly";}	// past 7 days
if ($mod > mktime(0,0,0) - 86400)	{$GOOGLEpriority = "0.9"; $GOOGLEfreq = "daily";}	// yesterday
if ($GOOGLEmoddate == date("Y-m-d"))	{$GOOGLEpriority = "1.0"; $GOOGLEfreq = "hourly";}	// today



IDIF is a stupid format: it includes the entire blog_contents, so the files are huge. In the process of setting this up, I learned that flat files have a maximum size of 1.4 megs or so (the size of an old floppy disk), so I had to create more than one.

Which explains the stupid concept of a "pointer file"; instead of just giving Yahoo the IDIF file itself, you give it a pointer file with URLs pointing to the multitude of IDIF files. Really stupid.

News flash, after finding the Journal Of Ovid on the web, I learned about length restrictions for the input fields (described below). This information was not contained on the Yahoo web site describing their file format. It considerably reduced the file sizes but I retained the structure of multiple files because who knows what I'll learn next?

IDIF title must be a maximum of 80 characters
IDIF description must be a maximum of 180 characters
IDIF body must be a maximum of 1000 characters
I'm only guessing about keywords

Thanks to the Journal Of Ovid on the web for this secret information

From the inside out: trim, replace whitespace (thanks to the PHP manual for this), shorten to maximum length

$IDIFtitle		= substr( preg_replace ('/\s\s+/', ' ', trim($title) ), 0, 80 );
$IDIFdescription	= substr( preg_replace ('/\s\s+/', ' ', trim($description) ), 0, 180 );
$IDIFkeywords		= substr( preg_replace ('/\s\s+/', ' ', trim($keywords) ), 0, 79 ) . " ";
$IDIFblog_contents	= substr( preg_replace ('/\s\s+/', ' ', trim($blog_contents) ), 0, 1000 );

Yahoo is said to support a simple text file list of URLs "urllist.txt" Documentation, of course, is scarce


(my thanks to http://centricle.com/tools/html-entities/ for HTML encoding)

Call KML files from within a blog or topic

Here's how to create a button in your blogs or topics that calls KML or KMZ files you create. In the Modify A Blog utility you can include a KML or KMZ file, but to call it explicity from within the blog, you can create a button as shown here.

  1. Create and save your KML file.
  2. FTP the file to the kml folder in Philadelphia Reflections
  3. Use the following code in a blog or topic to call the kml file


<button onclick="location.href='http://www.philadelphia-reflections.com/kml-read.php?file=Franklin.kmz'">Button Label</button>

To create this button:



Instead of Franklin.kmz, put any .kml or .kmz file that is in the kml folder:
http://www.philadelphia-reflections.com/kml/

BU to Pier 7 GPS Tour

Example of Including a KML file using the GPS tour from BU to Pier 7

Images

The panel below shows every image (2000+) in every blog (800+) on Philadelphia Reflections starting with most recent additions.

It works better on some browsers especially Firefox than others, and -- with 2000 images -- it takes a while to load, as much as 10 minutes on a slow connection. An icon in the corner of the picture-wall starts a slideshow. Note: Mouse-clicking enlarges each thumbnail picture, displaying an icon linked to the website source page. We suggest you try out every little icon to see the amazing versatility of Cooliris.

Get Adobe Flash

QR Codes

QR Codes are similar to bar codes in that they are read optically. Most-common in Japan, all Japanese cell phones can read them; all fancy phones in America (iPhone, etc.) have downloadable apps that can read QR Codes (semacode is a free QR Code app for the iPhone but there are many for all).

One application that is becoming common is encoding a website's URL and including the image in a print advertisement.

The QR Codes below were created by http://qrcode.kaywa.com/; create QR and semacode/DataMatrix from text: http://invx.com/code/.

QR Codes
{philadelphia reflections qrcode} {george fisher qr code}
Philadelphia Reflections George Fisher (Flash... N/G on iPhone)
{chemical heritage society qr code} {kaiser qr code}
Chemical Heritage Society Kaiser Permanente
{george fisher advisors qr code}
George Fisher Advisors QR Code George Fisher Advisors semacode/DataMatrix

Unemployment 2008/09

Python URL Handling

In case you're wondering "How the heck does Python handle headers and data under 3.2.2?", here's an example that works using IDLE and Python 3.2.2 installed on a 64-bit Windows 7 machine.

import re
import urllib.request
url = "http://www.philadelphia-reflections.com"

uf = urllib.request.urlopen(url)

# header information
print('--- headers ---')
info = uf.info()  # headers

#headers = info._headers # a list of all the headers

print('charsets:',info.get_charsets())
print('content_charset:',info.get_content_charset()) 
print('content_type:',info.get_content_type())
print('content_maintype:',info.get_content_maintype())
print('content_subtype:',info.get_content_subtype())
print('default_type:',info.get_default_type())
print('filename:',info.get_filename())
print('params:',info.get_params())
print('payload:',info.get_payload())

print()
print('--- data ---')

data = uf.read().decode(info.get_content_charset()) # content
print(data[:500])

print()
print('--- image ---')

imageurl = url + "/images/001.JPG"
image = urllib.request.urlretrieve(imageurl, 'python_001.jpg')
print(image)

Real Estate Investment Calculator

Click here for the calculator link

Iterate through a Word document, modifying picture properties(Blog 2300)

(Blog 2300) We have a facility on this website to download books of many chapters (made up of volumes of topics on the site) to Microsoft Word for subsequent editing and eventual publishing. In many cases we download lots of pictures (via an img src= tag). I have not found a way to set the way text flows around the images in Word using HTML or CSS, so I built a Word macro to do it. This should allow you to change the size of images, as well as move them around. Moving the captions requires the use of the captions feature in Word's image menu (right-click).

------------------------------------

Instructions for use of a Macro named Sub ImageFlow():

  1. Open Word

  2. In Word, enter File>Open

  3. enter the URL of the file you want to modify into the File Entry box and press the Enter key to load the document. It may take a minute or two, but a working screen should appear, loaded with the file in a condition ready to move the pictures around.

  4. Press Alt + F11 which will open the VBA screen

  5. Copy the macro found on this page from
    Sub ImageFlow()
    to
    End Sub
  6. In the right-hand panel of the VBA screen press Ctrl+A, Ctrl+V to paste it in

  7. In the VBA screen press F5 to run the macro

If you want to do a lot of these manipulations, save the macro in the Macro Library of Windows Word.

------------------------------------
Sub ImageFlow()
'
'  this Macro goes through an entire Word document and
'  changes the way text flows around each picture
'  ("Tight" in this example but see below for choices)
'
    Dim shpIn As InlineShape, shp As Shape

    For Each shpIn In ActiveDocument.InlineShapes
        If (shpIn.Type = wdInlineShapeLinkedPicture) Then
            Set shp = shpIn.ConvertToShape
            shp.WrapFormat.Type = wdWrapTight
        End If
    Next shpIn

    For Each shp In ActiveDocument.Shapes
        shp.WrapFormat.Type = wdWrapTight
    Next shp

End Sub
----------------------------------------

Change wdWrapTight to any of the following:
wdWrapBehind
wdWrapFront
wdWrapInline
wdWrapNone
wdWrapSquare
wdWrapThrough
wdWrapTight
wdWrapTopBottom

My thanks to http://www.phrebh.com/Jenius/252-center-pictures-in-word-with-vba/ for showing me the essential technique of iterating through the pictures.

What are the InlineShapes' Types? See http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.inlineshape.type(v=office.11).aspx; it is possible we may also need to select on wdInlineShapePicture (as well as wdInlineShapeLinkedPicture) but for my specific purpose I did not need to.

Central Securities

 

Please Let Us Know What You Think

 
 

(HTML tags provide better formatting)
 

63 Blogs

The Evolution of a Programmer
Excellence depends upon simplicity

Book Proposal: Investing
Investing for Cash Flow
Individual and institutional investors must change their investment style to survive financial crises

Web Standards Validation
It is important to confirm that your website conforms to standards

Floating Three-Column CSS Layout
A popular web page layout is three columns with a header and footer. This is achieved on this web site with CSS using floating columns.

Valid XHTML YouTube embed code generator
This free tool will create a valid XHTML embed code for any YouTube video. The code YouTube shows on the embed field is not valid XHTML! However, you can simply use this simple tool to make it Valid XHTML 1.0 Transitional.

XHTML vs. HTML
XHTML is advanced HTML. Not all browsers support it, so pages must test first and serve what's supported.

PHP output buffering improves response time. Gzip speeds internet transmission, compressing text volume (not images) up to 80%.

HTML Forms
How to open a form in a new window when a radio button is clicked.

Sold Out
How Wall Street bought Washington ... How Washington sold out to Wall Street.

mysql_insert_assoc
How to make MySQL insertions easier (and safe)

mysql_update_assoc
Easily (and quote_smart-ly) update a record in a MySQL database table

MySQL server has gone away
What to do when your MySQL connection is timing out for no apparently good reason, all of a sudden.

DHTML, PHP and MySQL References
What are good references for advanced website development?

SQL To Exclude A List Of Items
How do you select everything from one table except for a list contained in another table?

Google Maps Icons
Google Maps/Earth do not make icon creation & manipulation easy.

Internet, Websites, and related Programming
Technical Comments related to programming this and other websites require a special topic section of their own.

Ternary Operator and the IIF function
Reduce the PHP If function and/or include it in a function

PHP out of memory condition
PHP scripts sometime run out of internal memory. Here's how to get around the problem.

Create and send CSV files from PHP
The ability to create a CSV file from MySQL data in PHP, download it and have it open automatically in Excel is very handy.

PHP script to display Google PageRank
It is very handy to know the Google PageRank of your pages. Here's a PHP script that figures it out for you.

Javascript: document.write and XHTML
Document.write does not work with "true" XHTML. Don't bother trying to fix the javascript.

HTML Anchor without an HREF?
How to execute a JavaScript function and nothing else.

Parsing name-value pair attributes in an HTML tag
Regexp HTML Attribute Parsing: Pulling out the value of numerous attributes in an HTML tag is a mind bender

Embed Flash as Valid XHTML
The embed tag doesn't validate with XHTML. Here's what to do.

Open a new window with XHTML
Prior to XHTML, you could open a new window with a link by saying target="_blank". That's no longer allowed, but what can you do?

Ampersand Madness: Convert &#x26; to &#x26;amp; to prevent XHTML errors
A regex solution to the huge problem of ampersand encoding in XHTML

Escaping for PHP Output to JavaScript
To send data to a JavaScript script from PHP, three levels of escaping are required

Server-Side gzip Compression
You can include code in a PHP program to compress an outbound web page. It works, but instructing the web server to do it to every page is much easier.

Process .htm and .html as php
How to include php scripts in html files

Send a KML file from disk using PHP
Preprocessing a kml or kmz disk file improves the user experience

Static vs Dynamic URLs
Implementing static URLs for a website driven by PHP and MySQL is as easy as a little regex and htaccess magic.

Captcha
Captcha is the term for security codes the user must enter into a form

CSS Zen Garden Suggestions
Here's a list of the designs I think are worth a look, illustrating the great power of CSS.

Font Families
A survey of the most-commonly installed fonts found on Windows machines

Emails From Iraq (2)
Iraq and a hard place: email record in 2007 from a young American in Iraq to work as a consultant to a local company

Geo Positioning
With the advent of Google Earth, the tagging of websites, blogs and photographs with latitude and longitude information has taken a great leap forward.

Round the Block in Haddonfield
Walking the dog in Haddonfield can be complex.

Find your location
Browsers are starting to support features of the new HTML 5 standard ... such as geo location. Not IE, of course, but try Firefox.

Date Math
If the function to calculate the number of days between two dates isn't built in, it's a pain to figure out

Web hosting providers
We have used two service providers: one good, the other poor.

Regular Expressions
Regular Expressions, regex, are an obscure but very powerful pattern-matching tool that every developer should learn.

Retirement Planning Video
The retirement situation and how much to save for yourself.

Debunking third-world myths with the best stats you've ever seen
Guaranteed: You've never seen data presented like this. Trends come to life. And the big picture snaps into sharp focus.

Income vs Life Expectancy over time
A graph that shows life expectancy increased over the years as the income of third-world countries grows.

SMTP Authorization and Handling Bounced Emails with PEAR Mail
Sign on to an SMTP server and get bounced emails returned to you

Data Sources for Health Care
REVENUE PROVIDERS WITH POTENTIALLY USEFUL MEDICAL DATA, MOSTLY UNUSED

Website Test Results
Response time test with lots of imagesPhiladelphia Reflections has excellent response time

CNBC Exposed
Finally some straight talk about the preeminent business news channel. From the Daily Show with Jon Stewart.

Macroeconomics of The 2007 Collapse
/>What happened to America in 2007 has happened to hundreds of developing economies in the past fifty years.
	</p>
                
                    <p class= Existing Websites Which Offer Higher Education
The number of Internet websites which currently offer free education on the college level is immense and growing rapidly. Just as terabyte is the next step after gigabyte, we need a new word to denominate "much larger than merely immense".

Regex URL Matching
On this site we check for the existence of a URL whenever an entry is updated. A Regex (regular expression) string was the breakthrough.

Health Expenditures as a percent of GDP
The US leads the world in health expenditures as a percent of GDP and the number is growing. Is this a meaningful statement?

Forbidden SNL Clip
Forbidden SNL Clip

Webpage Printing
Webpage printing is supported on this site. It seems to work pretty well except for text flow-around for some browsers.

RSS, Atom, Syndication, etc.
The world is full of XML and XML-like file formats for syndication-feed purposes. Why they must all be different, God alone can tell. But the reason there is lousy documentation is the evil work of Man.

Call KML files from within a blog or topic
How to create a button to call a KML or KMZ file

BU to Pier 7 GPS Tour
Example of Including a KML file

Images
The 1000+ images on Philadelphia Reflections are displayed at this location. It works better with some browsers than others.

QR Codes
QR Codes are becoming common in print ads to encode the sponsor's URL

Unemployment 2008/09
The average national unemployment rate of 10.6% does not convey the same impact as seeing the spread of it over time. Tune in for a 30-second display of a graphics display.

Python URL Handling
An example of URL handling using Python 3.2.2 installed on Windows 7

Real Estate Investment Calculator
The price you should pay for an income-producing property is a function of the cash flow. Too many investors look at criteria other than cash flow and end up making bad investment decisions.

Iterate through a Word document, modifying picture properties(Blog 2300)
Iterate through a Word document modifying the Wrap Text property of every picture

Central Securities
An analysis of Central Securities (CET).