From a420f03f20c6f3383f3d7a6eb34bb7812540b80c Mon Sep 17 00:00:00 2001 From: zapata Date: Wed, 24 Sep 2003 02:08:04 +0000 Subject: [PATCH] - multiple "producer" shortcuts possible - some fixes here and there --- bundles/admin_en.properties | 6 +- source/default.properties | 9 +- .../mircoders/localizer/MirProducerLocalizer.java | 18 +- .../localizer/basic/MirBasicProducerLocalizer.java | 341 +++++++++++---------- source/mircoders/servlet/ServletModuleAdmin.java | 1 + source/mircoders/servlet/ServletModuleContent.java | 7 +- .../mircoders/servlet/ServletModuleProducer.java | 7 +- source/tool/BundleTool.java | 48 ++- templates/admin/FUNCTIONS_media.template | 2 +- templates/admin/mediafolderlist.template | 47 ++- templates/admin/producerqueue.template | 6 +- templates/admin/start_admin.template | 11 +- web/style/admin.css | 13 +- 13 files changed, 292 insertions(+), 224 deletions(-) diff --git a/bundles/admin_en.properties b/bundles/admin_en.properties index cdff95a8..f136cba6 100755 --- a/bundles/admin_en.properties +++ b/bundles/admin_en.properties @@ -1,6 +1,6 @@ ########## admin ########## # language: english -# $Id: admin_en.properties,v 1.48.2.13 2003/09/19 23:34:14 zapata Exp $ +# $Id: admin_en.properties,v 1.48.2.14 2003/09/24 02:08:04 zapata Exp $ languagename=English @@ -312,6 +312,8 @@ start.allcommentswithstatus={0} start.producers.title=GENERATE MANUALLY start.producers.produceAllNew=generate all new +start.producers.recipe.allnew=generate all new + start.producers.advanced=advanced page (use with care!) start.administer.title=ADMINISTER @@ -524,4 +526,4 @@ user.error.incorrectpassword= Incorrect password ########## infomessages ########## infomessage.htmltitle = Information -infomessage.produceAllNewAddedToQueue = Your request has been added to the queue. +infomessage.recipeAddedToQueue = Your request has been added to the queue. diff --git a/source/default.properties b/source/default.properties index 4b8708a1..f7d3a0bf 100755 --- a/source/default.properties +++ b/source/default.properties @@ -143,15 +143,10 @@ Mir.Localizer.OpenPosting.ContentProducers= media.new;articles.changed;startpage Mir.Localizer.OpenPosting.CommentProducers= articles.changed;synchronization.run # Which producers need to be called after the "produce all new" link is clicked from admin -Mir.Localizer.Producer.AllNewProducers= media.new;articles.changed;startpage.run;synchronization.run +Mir.Localizer.Producer.ProducerRecipes= + allnew = media.new;articles.changed;startpage.run;synchronization.run -#note that you can't make pdf's without making fo's -#this is actually now set in producers.xml -#but these summarize what is said in there for the benefit of OpenMir -GenerateFO=yes -GeneratePDF=yes - #use rsync to mirror the website to a remote-host Rsync=no Rsync.Script.Path=/var/www/bin/rsync-copy diff --git a/source/mircoders/localizer/MirProducerLocalizer.java b/source/mircoders/localizer/MirProducerLocalizer.java index 7090d486..b389f8fe 100755 --- a/source/mircoders/localizer/MirProducerLocalizer.java +++ b/source/mircoders/localizer/MirProducerLocalizer.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ package mircoders.localizer; @@ -36,5 +36,7 @@ import mir.producer.ProducerFactory; public interface MirProducerLocalizer { public List factories() throws MirLocalizerExc, MirLocalizerFailure; public ProducerFactory getFactoryForName(String aName); - public void produceAllNew(); + + public List getRecipeNames() throws MirLocalizerExc, MirLocalizerFailure; + public void produceRecipe(String aName) throws MirLocalizerExc, MirLocalizerFailure; } diff --git a/source/mircoders/localizer/basic/MirBasicProducerLocalizer.java b/source/mircoders/localizer/basic/MirBasicProducerLocalizer.java index a54ba004..75157141 100755 --- a/source/mircoders/localizer/basic/MirBasicProducerLocalizer.java +++ b/source/mircoders/localizer/basic/MirBasicProducerLocalizer.java @@ -1,154 +1,187 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mircoders.localizer.basic; - -import java.io.File; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import mir.entity.adapter.EntityAdapterModel; -import mir.generator.Generator; -import mir.generator.WriterEngine; -import mir.log.LoggerWrapper; -import mir.producer.ProducerFactory; -import mir.producer.reader.DefaultProducerNodeBuilders; -import mir.producer.reader.ProducerConfigReader; -import mir.producer.reader.ProducerNodeBuilderLibrary; -import mir.util.FileMonitor; -import mircoders.global.MirGlobal; -import mircoders.global.ProducerEngine; -import mircoders.localizer.MirLocalizerExc; -import mircoders.localizer.MirLocalizerFailure; -import mircoders.localizer.MirProducerLocalizer; -import mircoders.producer.reader.SupplementalProducerNodeBuilders; - -public class MirBasicProducerLocalizer implements MirProducerLocalizer { - private List producerFactories; - private Map nameToFactory; - private List allNewProducerTasks; - - protected FileMonitor fileMonitor; - protected EntityAdapterModel model; - protected Generator.GeneratorLibrary generatorLibrary; - protected WriterEngine writerEngine; - - protected LoggerWrapper logger; - - public MirBasicProducerLocalizer() { - try { - logger = new LoggerWrapper("Localizer.Basic.Producer"); - - String allNewProducers = MirGlobal.config().getString("Mir.Localizer.Producer.AllNewProducers"); - allNewProducerTasks = ProducerEngine.ProducerTask.parseProducerTaskList(allNewProducers); - - producerFactories = new Vector(); - model = MirGlobal.localizer().dataModel().adapterModel(); - generatorLibrary = MirGlobal.localizer().generators().makeProducerGeneratorLibrary(); - writerEngine = MirGlobal.localizer().generators().makeWriterEngine(); - nameToFactory = new HashMap(); - } - catch (Throwable t) { - logger.error("MirBasicProducerLocalizer(): Exception "+t.getMessage()); - model = new EntityAdapterModel(); - } - } - - public List factories() throws MirLocalizerExc { - if (fileMonitor==null || producerFactories == null || fileMonitor.hasChanged()) { - try { - List newProducers = new Vector(); - FileMonitor newFileMonitor = new FileMonitor(); - setupFactories(newProducers, newFileMonitor); - - producerFactories = newProducers; - fileMonitor = newFileMonitor; - logger.info("MirBasicProducerLocalizer.factories(): successfully setup factories"); - - nameToFactory.clear(); - Iterator i = producerFactories.iterator(); - while (i.hasNext()) { - ProducerFactory factory = (ProducerFactory) i.next(); - nameToFactory.put(factory.getName(), factory); - } - } - catch (Throwable t) { - logger.error("MirBasicProducerLocalizer.factories(): Unable to setup factories: "+t.getMessage()); - t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE)); - } - } - - return producerFactories; - }; - - protected void setupProducerNodeBuilderLibrary(ProducerNodeBuilderLibrary aLibrary) throws MirLocalizerFailure { - try { - DefaultProducerNodeBuilders.registerBuilders( - aLibrary, model, generatorLibrary, writerEngine, - MirGlobal.config().getString("Home"), MirGlobal.config().getString("Producer.StorageRoot")); - SupplementalProducerNodeBuilders.registerBuilders(aLibrary, model); - } - catch (Throwable t) { - throw new MirLocalizerFailure(t.getMessage(), t); - } - } - - protected void setupFactories(List aFactories, FileMonitor aFileMonitor) throws MirLocalizerExc, MirLocalizerFailure { - ProducerConfigReader reader; - ProducerNodeBuilderLibrary library = new ProducerNodeBuilderLibrary(); - setupProducerNodeBuilderLibrary(library); - List usedFiles = new Vector(); - Iterator i; - - aFileMonitor.clear(); - reader = new ProducerConfigReader(); - reader.parseFile(MirGlobal.config().getString("Home") + File.separatorChar + MirGlobal.config().getString("Mir.Localizer.ProducerConfigFile"), library, aFactories, usedFiles); - - i = usedFiles.iterator(); - while (i.hasNext()) - aFileMonitor.addFile((File) i.next()); - } - - public void produceAllNew() { - MirGlobal.producerEngine().addTasks(allNewProducerTasks); - }; - - public ProducerFactory getFactoryForName(String aName) { - try { - factories(); - } - catch (Throwable t) { - } - - return (ProducerFactory) nameToFactory.get(aName); - } -} +/* + * Copyright (C) 2001, 2002 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mircoders.localizer.basic; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import mir.entity.adapter.EntityAdapterModel; +import mir.generator.Generator; +import mir.generator.WriterEngine; +import mir.log.LoggerWrapper; +import mir.producer.ProducerFactory; +import mir.producer.reader.DefaultProducerNodeBuilders; +import mir.producer.reader.ProducerConfigReader; +import mir.producer.reader.ProducerNodeBuilderLibrary; +import mir.util.*; +import mircoders.global.MirGlobal; +import mircoders.global.ProducerEngine; +import mircoders.localizer.MirLocalizerExc; +import mircoders.localizer.MirLocalizerFailure; +import mircoders.localizer.MirProducerLocalizer; +import mircoders.producer.reader.SupplementalProducerNodeBuilders; + +public class MirBasicProducerLocalizer implements MirProducerLocalizer { + private List producerFactories; + private Map nameToFactory; + + private Map producerRecipes; + private List producerRecipeNames; + + protected FileMonitor fileMonitor; + protected EntityAdapterModel model; + protected Generator.GeneratorLibrary generatorLibrary; + protected WriterEngine writerEngine; + + protected LoggerWrapper logger; + + public MirBasicProducerLocalizer() { + try { + logger = new LoggerWrapper("Localizer.Basic.Producer"); + + producerRecipes = new HashMap(); + producerRecipeNames = new Vector(); + + String[] recipes = MirGlobal.config().getStringArray("Mir.Localizer.Producer.ProducerRecipes"); + for (int i = 0; i0) { + producerRecipes.put("allnew", ProducerEngine.ProducerTask.parseProducerTaskList(allNewProducers)); + producerRecipeNames.add("allnew"); + } + + producerFactories = new Vector(); + model = MirGlobal.localizer().dataModel().adapterModel(); + generatorLibrary = MirGlobal.localizer().generators().makeProducerGeneratorLibrary(); + writerEngine = MirGlobal.localizer().generators().makeWriterEngine(); + nameToFactory = new HashMap(); + } + catch (Throwable t) { + logger.error("MirBasicProducerLocalizer(): Exception "+t.getMessage()); + model = new EntityAdapterModel(); + } + } + + public List getRecipeNames() throws MirLocalizerExc, MirLocalizerFailure { + return producerRecipeNames; + } + + public void produceRecipe(String aName) throws MirLocalizerExc, MirLocalizerFailure { + if (producerRecipes.containsKey(aName)) + MirGlobal.producerEngine().addTasks((List) producerRecipes.get(aName)); + else + throw new MirLocalizerExc("Unknown recipe name: " + aName); + } + + public List factories() throws MirLocalizerExc { + if (fileMonitor==null || producerFactories == null || fileMonitor.hasChanged()) { + try { + List newProducers = new Vector(); + FileMonitor newFileMonitor = new FileMonitor(); + setupFactories(newProducers, newFileMonitor); + + producerFactories = newProducers; + fileMonitor = newFileMonitor; + logger.info("MirBasicProducerLocalizer.factories(): successfully setup factories"); + + nameToFactory.clear(); + Iterator i = producerFactories.iterator(); + while (i.hasNext()) { + ProducerFactory factory = (ProducerFactory) i.next(); + nameToFactory.put(factory.getName(), factory); + } + } + catch (Throwable t) { + logger.error("MirBasicProducerLocalizer.factories(): Unable to setup factories: "+t.getMessage()); + t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE)); + } + } + + return producerFactories; + }; + + protected void setupProducerNodeBuilderLibrary(ProducerNodeBuilderLibrary aLibrary) throws MirLocalizerFailure { + try { + DefaultProducerNodeBuilders.registerBuilders( + aLibrary, model, generatorLibrary, writerEngine, + MirGlobal.config().getString("Home"), MirGlobal.config().getString("Producer.StorageRoot")); + SupplementalProducerNodeBuilders.registerBuilders(aLibrary, model); + } + catch (Throwable t) { + throw new MirLocalizerFailure(t.getMessage(), t); + } + } + + protected void setupFactories(List aFactories, FileMonitor aFileMonitor) throws MirLocalizerExc, MirLocalizerFailure { + ProducerConfigReader reader; + ProducerNodeBuilderLibrary library = new ProducerNodeBuilderLibrary(); + setupProducerNodeBuilderLibrary(library); + List usedFiles = new Vector(); + Iterator i; + + aFileMonitor.clear(); + reader = new ProducerConfigReader(); + reader.parseFile(MirGlobal.config().getString("Home") + File.separatorChar + MirGlobal.config().getString("Mir.Localizer.ProducerConfigFile"), library, aFactories, usedFiles); + + i = usedFiles.iterator(); + while (i.hasNext()) + aFileMonitor.addFile((File) i.next()); + } + + public ProducerFactory getFactoryForName(String aName) { + try { + factories(); + } + catch (Throwable t) { + } + + return (ProducerFactory) nameToFactory.get(aName); + } +} diff --git a/source/mircoders/servlet/ServletModuleAdmin.java b/source/mircoders/servlet/ServletModuleAdmin.java index ec85a080..db2cdf1e 100755 --- a/source/mircoders/servlet/ServletModuleAdmin.java +++ b/source/mircoders/servlet/ServletModuleAdmin.java @@ -91,6 +91,7 @@ public class ServletModuleAdmin extends ServletModule mergeData.put("searcharticletype", null); mergeData.put("searchorder", null); mergeData.put("selectarticleurl", null); + mergeData.put("recipes", MirGlobal.localizer().producers().getRecipeNames()); ServletHelper.generateResponse(aResponse.getWriter(), mergeData, startTemplate); } diff --git a/source/mircoders/servlet/ServletModuleContent.java b/source/mircoders/servlet/ServletModuleContent.java index 63dd5a99..c9ef69f9 100755 --- a/source/mircoders/servlet/ServletModuleContent.java +++ b/source/mircoders/servlet/ServletModuleContent.java @@ -61,7 +61,7 @@ import mircoders.storage.DatabaseContentToTopics; * ServletModuleContent - * deliver html for the article admin form. * - * @version $Id: ServletModuleContent.java,v 1.52.2.10 2003/09/21 16:40:41 zapata Exp $ + * @version $Id: ServletModuleContent.java,v 1.52.2.11 2003/09/24 02:08:04 zapata Exp $ * @author rk, mir-coders * */ @@ -384,11 +384,6 @@ public class ServletModuleContent extends ServletModule responseData.put("topics", topicsList); -/* - responseData.put("topics", - new EntityIteratorAdapter("", configuration.getString("Mir.Localizer.Admin.TopicListOrder"), - 20, MirGlobal.localizer().dataModel().adapterModel(), "topic")); -*/ responseData.put("returnurl", requestParser.getParameter("returnurl")); responseData.put("thisurl", urlBuilder.getQuery()); diff --git a/source/mircoders/servlet/ServletModuleProducer.java b/source/mircoders/servlet/ServletModuleProducer.java index d8281ee0..e1e79402 100755 --- a/source/mircoders/servlet/ServletModuleProducer.java +++ b/source/mircoders/servlet/ServletModuleProducer.java @@ -161,10 +161,11 @@ public class ServletModuleProducer extends ServletModule } } - public void produceAllNew(HttpServletRequest aRequest, HttpServletResponse aResponse) { + public void producerecipe(HttpServletRequest aRequest, HttpServletResponse aResponse) { try { - MirGlobal.localizer().producers().produceAllNew(); - showMessage(aRequest, aResponse, "produceAllNewAddedToQueue", "", ""); + String recipe = aRequest.getParameter("recipe"); + MirGlobal.localizer().producers().produceRecipe(recipe); + showMessage(aRequest, aResponse, "recipeAddedToQueue", recipe, ""); } catch (Throwable t) { throw new ServletModuleFailure(t); diff --git a/source/tool/BundleTool.java b/source/tool/BundleTool.java index e44345b0..52e28f7c 100755 --- a/source/tool/BundleTool.java +++ b/source/tool/BundleTool.java @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. * If you do not wish to do so, delete this exception statement from your version. */ @@ -34,7 +34,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.util.Iterator; +import java.util.*; import mir.util.ExceptionFunctions; import mir.util.PropertiesManipulator; @@ -219,6 +219,23 @@ public class BundleTool { } } + public static void rename(String anOldKeyName, String aNewKeyName, List aBundles) { + /* + PropertiesManipulator bundle; + + try { + bundle = PropertiesManipulator.readProperties(new FileInputStream(new File(aBundle))); + + PropertiesManipulator.writeProperties(bundle, new FileOutputStream(anOutputFile), anEncoding, false); + } + catch (Throwable t) { + System.out.println("Unable to read master properties: " + t.getMessage()); + return; + } +*/ + } + + public static void main(String[] anArguments) { String command = "help"; @@ -253,9 +270,19 @@ public class BundleTool { return; } } - } + else if (command.equals("rename")) { + if (anArguments.length>=3) { + List arguments = Arrays.asList(anArguments); + rename(anArguments[0], anArguments[1], arguments.subList(2, arguments.size())); +/* + decode(anArguments[1], anArguments[2], anArguments[3]); +*/ + return; + } + } + } System.out.println("Usage:"); @@ -274,6 +301,9 @@ public class BundleTool { System.out.println(" BundleTool decode "); System.out.println(""); System.out.println(" Decodes the keys/values with a custom encoding."); + System.out.println(" BundleTool rename [ [ ... ]]"); + System.out.println(""); + System.out.println(" Decodes the keys/values with a custom encoding."); } } \ No newline at end of file diff --git a/templates/admin/FUNCTIONS_media.template b/templates/admin/FUNCTIONS_media.template index 39d73b45..af0c5778 100755 --- a/templates/admin/FUNCTIONS_media.template +++ b/templates/admin/FUNCTIONS_media.template @@ -7,7 +7,7 @@ -
+ diff --git a/templates/admin/mediafolderlist.template b/templates/admin/mediafolderlist.template index 3d7a30a6..5399c916 100755 --- a/templates/admin/mediafolderlist.template +++ b/templates/admin/mediafolderlist.template @@ -6,38 +6,31 @@ + - + - - - - - - - - - - - - - + + + + + + + + diff --git a/templates/admin/producerqueue.template b/templates/admin/producerqueue.template index 9466eeca..9cb10ce6 100755 --- a/templates/admin/producerqueue.template +++ b/templates/admin/producerqueue.template @@ -28,7 +28,11 @@ class="listrow2"class="listrow2"> ${v.name} - ${v.description} + ${v.description} + +
+ + diff --git a/templates/admin/start_admin.template b/templates/admin/start_admin.template index 2931a853..bf84e04f 100755 --- a/templates/admin/start_admin.template +++ b/templates/admin/start_admin.template @@ -110,10 +110,15 @@

${lang("start.producers.title")}

-

- > ${lang("start.producers.produceAllNew")}
+

${lang("start.superusermenu")} diff --git a/web/style/admin.css b/web/style/admin.css index a62a3fc2..fb5d8ce3 100755 --- a/web/style/admin.css +++ b/web/style/admin.css @@ -188,17 +188,23 @@ a:hover { .majorbutton { background-color:#DDDDDD; + font-size:0.9em; color: #990000; font-weight: bold; border: 1px solid #990000; - bevel: 2px solid #990000; + margin:2px; + padding:2px; + padding-left:8px; + padding-right:8px; } .minorbutton { background-color:#DDDDDD; color: #990000; - font-size:1em; + font-size:0.9em; + border: 1px solid #990000; padding:2px; + margin:2px; padding-left:8px; padding-right:8px; // border:1px solid #990000; @@ -209,7 +215,8 @@ a:hover { color: #990000; font-size:0.9em; margin: 0px; - padding:0px; + border: 1px solid #990000; + padding:2px; /* padding-left:2px; padding-right:2px; -- 2.11.0