Doctype made no sense! It was a write-only property in some cases, and uses

itself and DoctypeMode to make up for Tidy's ability to store only a single
value for an option. It's a little bit special relative to every single other
option, in that it's declared as a string, but also has a picklist. This change
makes Doctype behave in the way every other Tidy option behaves, and treats
Doctype as a string, but also supports selection via the picklist.
This commit is contained in:
Jim Derry 2017-11-16 15:07:52 -05:00
parent bb15427e73
commit e6c891ea00
4 changed files with 81 additions and 38 deletions

View file

@ -548,18 +548,6 @@ static void GetOption(TidyDoc tdoc, /**< The tidy document. */
/* Handle special cases first. */ /* Handle special cases first. */
switch ( optId ) switch ( optId )
{ {
case TidyDoctype:
d->type = "DocType";
d->vals = NULL;
{
ctmbstr sdef = NULL;
sdef = tidyOptGetCurrPick( tdoc, TidyDoctypeMode );
if ( !sdef || *sdef == '*' )
sdef = tidyOptGetValue( tdoc, TidyDoctype );
d->def = sdef;
}
break;
case TidyInlineTags: case TidyInlineTags:
case TidyBlockTags: case TidyBlockTags:
case TidyEmptyTags: case TidyEmptyTags:

View file

@ -180,7 +180,7 @@ static const TidyOptionImpl option_defs[] =
{ TidyCSSPrefix, MR, "css-prefix", ST, 0, ParseCSS1Selector, NULL, "c" }, { TidyCSSPrefix, MR, "css-prefix", ST, 0, ParseCSS1Selector, NULL, "c" },
{ TidyCustomTags, IR, "new-custom-tags", ST, 0, ParseList, NULL }, /* 20170309 - Issue #119 */ { TidyCustomTags, IR, "new-custom-tags", ST, 0, ParseList, NULL }, /* 20170309 - Issue #119 */
{ TidyDecorateInferredUL, MX, "decorate-inferred-ul", BL, no, ParsePickList, &boolPicks }, { TidyDecorateInferredUL, MX, "decorate-inferred-ul", BL, no, ParsePickList, &boolPicks },
{ TidyDoctype, DT, "doctype", ST, 0, ParseDocType, &doctypePicks }, { TidyDoctype, DT, "doctype", ST, TidyDoctypeAuto, ParseDocType, &doctypePicks },
#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifndef DOXYGEN_SHOULD_SKIP_THIS
{ TidyDoctypeMode, IR, "doctype-mode", IN, TidyDoctypeAuto, NULL, &doctypePicks }, { TidyDoctypeMode, IR, "doctype-mode", IN, TidyDoctypeAuto, NULL, &doctypePicks },
#endif #endif
@ -385,6 +385,28 @@ static Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val )
} }
ctmbstr TY_(GetPickListLabelForPick)( TidyOptionId optId, uint pick )
{
const TidyOptionImpl* option = TY_(getOption)( optId );
if ( option && option->pickList )
{
uint ix = 0;
const PickListItem *item = NULL;
/* Loop through the picklist until index matches the value. */
while ( (item = &(*option->pickList)[ ix ]) && item->label && ix<pick )
{
++ix;
}
if ( ix==pick && item->label )
return item->label;
}
return NULL;
}
Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val ) Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val )
{ {
Bool status = ( optId < N_TIDY_OPTIONS ); Bool status = ( optId < N_TIDY_OPTIONS );

View file

@ -203,6 +203,14 @@ void TY_(InitConfig)( TidyDocImpl* doc );
void TY_(FreeConfig)( TidyDocImpl* doc ); void TY_(FreeConfig)( TidyDocImpl* doc );
/** Gets the picklist label for a given value.
** @param optId the option id having a picklist to check.
** @param pick the picklist item to retrieve.
** @returns The label for the pick.
*/
ctmbstr TY_(GetPickListLabelForPick)( TidyOptionId optId, uint pick );
/** Sets the integer value for the given option Id. /** Sets the integer value for the given option Id.
** @param doc The Tidy document. ** @param doc The Tidy document.
** @param optId The option ID to set. ** @param optId The option ID to set.

View file

@ -366,6 +366,12 @@ TidyConfigCategory TIDY_CALL tidyOptGetCategory( TidyOption topt )
ctmbstr TIDY_CALL tidyOptGetDefault( TidyOption topt ) ctmbstr TIDY_CALL tidyOptGetDefault( TidyOption topt )
{ {
const TidyOptionImpl* option = tidyOptionToImpl( topt ); const TidyOptionImpl* option = tidyOptionToImpl( topt );
/* Special case for TidyDoctype, because it is declared as string */
if ( option && option->id == TidyDoctype )
{
const TidyOptionImpl* newopt = TY_(getOption)( TidyDoctypeMode );
return TY_(GetPickListLabelForPick)( TidyDoctypeMode, newopt->dflt );
}
if ( option && option->type == TidyString ) if ( option && option->type == TidyString )
return option->pdflt; /* Issue #306 - fix an old typo hidden by a cast! */ return option->pdflt; /* Issue #306 - fix an old typo hidden by a cast! */
return NULL; return NULL;
@ -375,6 +381,14 @@ ulong TIDY_CALL tidyOptGetDefaultInt( TidyOption topt )
const TidyOptionImpl* option = tidyOptionToImpl( topt ); const TidyOptionImpl* option = tidyOptionToImpl( topt );
if ( option && option->type != TidyString ) if ( option && option->type != TidyString )
return option->dflt; return option->dflt;
/* Special case for TidyDoctype, because it has a picklist */
if ( option->id == TidyDoctype )
{
const TidyOptionImpl* newopt = TY_(getOption)( TidyDoctypeMode );
return newopt->dflt;
}
return ~0U; return ~0U;
} }
Bool TIDY_CALL tidyOptGetDefaultBool( TidyOption topt ) Bool TIDY_CALL tidyOptGetDefaultBool( TidyOption topt )
@ -411,11 +425,26 @@ ctmbstr TIDY_CALL tidyOptGetNextPick( TidyOption topt, TidyIterator* pos )
ctmbstr TIDY_CALL tidyOptGetValue( TidyDoc tdoc, TidyOptionId optId ) ctmbstr TIDY_CALL tidyOptGetValue( TidyDoc tdoc, TidyOptionId optId )
{ {
TidyDocImpl* impl = tidyDocToImpl( tdoc ); TidyDocImpl* impl = tidyDocToImpl( tdoc );
ctmbstr optval = NULL; ctmbstr optval = NULL;
if ( impl ) if ( impl )
optval = cfgStr( impl, optId ); {
return optval; if ( optId == TidyDoctype )
{
/* Special case for TidyDoctype, because it has a picklist and is a string. */
uint pick = tidyOptGetInt( tdoc, TidyDoctypeMode );
if ( pick != TidyDoctypeUser )
{
optval = TY_(GetPickListLabelForPick)( TidyDoctypeMode, pick );
} else {
optval = cfgStr( impl, optId );
}
} else {
/* Standard case. */
optval = cfgStr( impl, optId );
}
}
return optval;
} }
Bool TIDY_CALL tidyOptSetValue( TidyDoc tdoc, TidyOptionId optId, ctmbstr val ) Bool TIDY_CALL tidyOptSetValue( TidyDoc tdoc, TidyOptionId optId, ctmbstr val )
{ {
@ -437,7 +466,13 @@ ulong TIDY_CALL tidyOptGetInt( TidyDoc tdoc, TidyOptionId optId )
TidyDocImpl* impl = tidyDocToImpl( tdoc ); TidyDocImpl* impl = tidyDocToImpl( tdoc );
ulong opti = 0; ulong opti = 0;
if ( impl ) if ( impl )
opti = cfg( impl, optId ); {
/* Special case for TidyDoctype, because it has a picklist */
if ( optId == TidyDoctype )
opti = cfg( impl, TidyDoctypeMode);
else
opti = cfg( impl, optId );
}
return opti; return opti;
} }
@ -445,7 +480,13 @@ Bool TIDY_CALL tidyOptSetInt( TidyDoc tdoc, TidyOptionId optId, ulong val
{ {
TidyDocImpl* impl = tidyDocToImpl( tdoc ); TidyDocImpl* impl = tidyDocToImpl( tdoc );
if ( impl ) if ( impl )
return TY_(SetOptionInt)( impl, optId, val ); {
/* Special case for TidyDoctype, because it has a picklist */
if ( optId == TidyDoctype )
return TY_(SetOptionInt)( impl, TidyDoctypeMode, val );
else
return TY_(SetOptionInt)( impl, optId, val );
}
return no; return no;
} }
@ -480,24 +521,8 @@ ctmbstr TIDY_CALL tidyOptGetEncName( TidyDoc tdoc, TidyOptionId optId )
ctmbstr TIDY_CALL tidyOptGetCurrPick( TidyDoc tdoc, TidyOptionId optId ) ctmbstr TIDY_CALL tidyOptGetCurrPick( TidyDoc tdoc, TidyOptionId optId )
{ {
const TidyOptionImpl* option = TY_(getOption)( optId ); uint pick = tidyOptGetInt( tdoc, optId );
return TY_(GetPickListLabelForPick)( optId, pick );
if ( option && option->pickList )
{
uint ix = 0;
uint pick = tidyOptGetInt( tdoc, optId );
const PickListItem *item = NULL;
// loop through the picklist until index matches the value
while ( (item = &(*option->pickList)[ ix ]) && item->label && ix<pick )
{
++ix;
}
if ( ix==pick && item->label )
return item->label;
}
return NULL;
} }