CSPro 8.1 Features: Question Text Logic


A beta version of CSPro 8.1 was released recently. In the run-up to the release, we will highlight some new features.

For years, CSPro has supported question text fills. Initially these were limited to replacement variables and occurrence labels and were defined like:

What is the relationship of %NAME% to the head of household?

Starting with CSPro 7.6, question text moved from RTF format to HTML, and the fill delimiters changed from % to ~~. The above question text was now written as:

<p>What is the relationship of ~~NAME~~ to the head of household?</p>

Introduced in CSPro 7.7, the templated reporting system introduced enhanced functionality, and any logic expression that evaluated to a number or string could be inserted in ~~ and ~~~ fills:

<p>What is the relationship of ~~NAME~~ to the head of household, ~~NAME(1)~~?</p>

This templated reporting system introduced new delimiters, <? ?>, that allowed logic to run during report generation without writing to the report directly as happens with the ~~ and ~~~ fills. However, this only applied to reports and not to question text.

Starting with CSPro 8.1, the evaluation of question text supports <? ?>. If you want to dynamically generate question text within a <? ?> block, you can use the QSF special name. For example, the above question text could be rewritten as:

<p>
    What is the relationship of
<? QSF.writeEncoded("%s", NAME); ?>
    to the head of household,
<? QSF.writeEncoded("%s", NAME(1)); ?>?
</p>

This is not a good use of <? ?>, as using ~~ is cleaner for simple text fills. However, this is very useful for creating tables or other dynamic question text features. For example, this question text displays the names and ages of people already entered in the household (for occurrences 2+):

<p>Enter for the name for person ~~curocc()~~.</p>

<?
if curocc() = 1 then
   
exit;
endif;
?>

<p>The following people have already been entered:</p>

<ul>
<?
do numeric ctr = 1 while ctr < curocc()
    QSF.
write("<li>");
    QSF.
writeEncoded("%s (age: %d)", NAME(ctr), AGE(ctr));
    QSF.
write("</li>");
enddo;
?>
</ul>

It is also possible to mix and match fills. Based on your coding preference, the bullet points could be written using:

<ul>
<? do numeric ctr = 1 while ctr < curocc() ?>
   
<li>~~NAME(ctr)~~ (age: ~~AGE(ctr)~~)</li>
<? enddo?>
</ul>

This feature, along with the ability to use Markdown in question text, is yet another step in the evolution of CSPro's question text functionality.

CSPro 8.1 Features: Synchronization Connection Strings


A beta version of CSPro 8.1 was released this week. In the run-up to the release, we will highlight some new features.

Prior to this version, when connecting to a synchronization service using syncconnect, you had to specify the type of the service. For example:

syncconnect(CSWeb, "https://example.org/csweb/api")

syncconnect(Dropbox)

Now, synchronization connection strings allow you to define all aspects of the connection in a single string. The above code could be rewritten as:

syncconnect("https://example.org/csweb/api")

syncconnect("Dropbox")

Connections strings have been used for data sources for several releases, and now are extended to synchronization connections. Specifying properties is the same as with data sources. This logic shows the old way of specifying a username and password, and how to do so by using the connection string:

syncconnect(CSWeb, "https://example.org/csweb/api""jackw""MyPa$$w0rd!")

syncconnect("https://example.org/csweb/api|username=jackw&password=MyPa%24%24w0rd%21")

When constructing property names and values from dynamic input, you can use the encode function to ensure that the strings are properly encoded:

string cswebConnection = maketext(
   
"https://example.org/csweb/api|username=%s&password=%s",
   
encode(PercentEncoding, "jackw"),
   
encode(PercentEncoding, "MyPa$$w0rd!")
);

syncconnect(cswebConnection);

Because a single string contains all information needed to make the connection, it is easy to change the synchronization service used by your application. For example, while testing, you may want to synchronize your data locally simply to test your application, and then may change to Dropbox for production. You could declare a variable that you can change once you move to production:

// for testing, sync with the data going in the directory: "local-sync-files"
string SyncService = "./local-sync-files|createDirectory=true";

// for production, comment the line above and enable the one below
// string SyncService = "Dropbox";

syncconnect(SyncService);

Happy 25th Birthday, CSPro!


The first version of CSPro, version 2.0, was released 25 years ago today. Only one member of the current development team was present for the first release, and some on the team were infants at the time! However, CSPro's legacy is not connected to any particular developer but instead belongs to the global community of users who have collected and processed data with CSPro over the years.

The first release, on May 5, 2000, occurred on a day that some had prophesied as the end of the world. On that day:

...all five naked-eye planets (Mercury, Venus, Mars, Jupiter, Saturn) plus the Moon and the Sun will at least approximately line-up. As viewed from planet Earth, they will be clustered within about 26 degrees, the closest alignment for all these celestial bodies since February 1962, when there was a solar eclipse!

NASA reassured the public not to worry:

On May 5, 2000 the planets Mercury, Venus, Earth, Mars, Jupiter, and Saturn will be more or less positioned in a line with the Sun. Additionally, the Moon will be almost lined up between the Earth and Sun. Although this has led to many dire predictions of global catastrophes such as melting ice caps, floods, hurricanes, earthquakes, etc. there is absolutely no scientific basis for these claims. The distance to the planets is too great for their gravity, magnetic fields, radiation, etc. to have any discernible effect on Earth. In fact, we won't even be able to see this alignment, as all the planets will be on the opposite side of the Sun from the Earth.

The world obviously did not end 25 years ago. Instead, that day was an auspicious beginning of a long run of success for CSPro. The team involved in the first release, heralding from the U.S. Census Bureau, Macro International, and Serpro S.A., could not have anticipated exactly how data collection would evolve over the decades, from keying paper forms to scanning to CAPI to CAWI, but they laid a strong foundation that has allowed CSPro to adapt to these changes, growing in a myriad of ways and finally becoming open source earlier this year.

To celebrate CSPro's 25th birthday, here are a few images from the first release:

v2-splash-screen
The splash screen used in CSPro version 2.0.

Computers are so fast these days, but 25 years ago, software often took a while to start, so many programs used splash screens to inform users that the program was still loading.

v2-new-file
The dialog to create a new file in CSPro version 2.0.

The first release did not contain a batch editing module. Data entry applications were also created with a few different files than are used now. There used to be a "skip code file" with the extension .skp, and the data entry application framework, now part of the .ent file, was instead an .apl (application) file.

v2-tools
The Designer's Tools menu in CSPro version 2.0.

CSPro's first release had only five tools. In contrast, CSPro 8.0 now includes 23 tools, reflecting how much the software has grown to support its users.

On May 5, 2000, no one could have predicted that CSPro would still be in use in 2025, and while we cannot say with certainty what the next 25 years will bring, CSPro has already built a lasting legacy. The software has been used to process billions of records, to collect and disseminate data for hundreds of censuses, and has been the software of choice for thousands of developers, all while remaining free thanks to generous support from USAID.

Happy 25th Birthday, CSPro! Or rather:

errmsg("Happy %d%s Birthday, CSPro!"25"th");

cupcakes-25
Cupcakes inscribed with 25 and CS to celebrate the big day!

Restoring Old Blog Posts


This upcoming Monday is the 25th anniversary of CSPro's first release. In anticipation of celebrating CSPro's longevity, I took a look at the second CSPro Users website, which was designed in WordPress:

2025-05-01-old-website

(The first website was designed with Drupal. The current version—the third iteration you are viewing now—is powered by Jekyll.)

We added a blog for the WordPress website but the posts did not make the transition when we moved to this new site. For this #ThrowbackThursday, I restored the 47 blog posts from the old site, originally published between December 2011 and March 2016.

If the blog looks different than you remember, that is because it is now generated using CSDocument. This tool, which also creates CSPro's documentation, colorizes code and automatically links functions and keywords to their help pages.

Although the blog has seen little activity over the past decade, we hope to post more frequently in the future.